Columns

Column Operations

Resize, reorder, pin and hide, from the pointer, the keyboard, the column menu or the API. All four are on by default, and each can be turned off on its own.

Basic Usage

Drag a header edge to resize, double-click that edge to autosize, drag a header to reorder, and open the menu at the end of a header to pin or hide. The readout below is the live column order, so every operation shows up in it.

order: name, email, team, role, country, salary, status
Email
Role
Country
Status (fixed)
Hoang Kowalski
hoang.kowalski1@example.com
Design
Manager
Poland
$127,691.00
invited
Bruno Nguyen
bruno.nguyen2@example.com
Growth
Support
Brazil
$105,146.00
invited
Bruno Dubois
bruno.dubois3@example.com
Design
Manager
Nigeria
$86,538.00
active
Farid Haddad
farid.haddad4@example.com
Growth
Analyst
Brazil
$76,443.00
suspended
Jonas Yilmaz
jonas.yilmaz5@example.com
Core
Support
Vietnam
$129,812.00
active
Quyen Tanaka
quyen.tanaka6@example.com
Growth
Analyst
France
$72,011.00
suspended
Mai Nguyen
mai.nguyen7@example.com
Support
Analyst
Brazil
$83,226.00
invited
Bruno Novak
bruno.novak8@example.com
Support
Analyst
Poland
$71,507.00
active
8 rows
import { columnOps, createDataGrid } from '@sv5ui/datagrid';

// All four operations are on by default. The shorthand form registers the
// feature for you; register it by hand to turn one off.
const grid = createDataGrid<Person>({
  data: people,
  columns,
  getRowId,
  features: [columnOps()]
});

// Or narrow it: this grid resizes and hides, but never reorders or pins.
columnOps({ resize: true, reorder: false, pin: false, hide: true });

// Pixels per keyboard resize step
columnOps({ resizeStep: 16 });

Narrowing What Is Allowed

The grid below registers columnOps({ reorder: false, pin: false }), so headers still resize and hide but cannot be dragged into a new order or pinned. A column can also refuse resizing on its own with resizable: false, which is what Status does in the first demo.

Name
Email
Team
Role
Hoang Kowalski
hoang.kowalski1@example.com
Design
Manager
Bruno Nguyen
bruno.nguyen2@example.com
Growth
Support
Bruno Dubois
bruno.dubois3@example.com
Design
Manager
Farid Haddad
farid.haddad4@example.com
Growth
Analyst
4 rows
// A column can opt out of resizing on its own, whatever the feature allows.
{ id: 'status', header: 'Status', width: 110, resizable: false }

// Starting state lives on the column, not on the feature.
{ id: 'name', header: 'Name', width: 200, pinned: 'left' }
{ id: 'country', header: 'Country', width: 150, hidden: true }

The Column Chooser

Hidden columns stay in the model, so the chooser can bring them back and an export can still name them. It lists only the columns your app declared: the selection checkbox, the row grip and the drawer a folded group leaves behind are the grid's own and never appear.

Hiding is not folding. A column put away here stays away when the group above it opens, and the two are kept in separate records, so ticking a column in the chooser never opens a single column in the middle of a closed group. Folding is on the Header Groups page, and both travel in a snapshot: columns by id, groups by their own.

Email
Role
Country
Status (fixed)
Hoang Kowalski
hoang.kowalski1@example.com
Design
Manager
Poland
$127,691.00
invited
Bruno Nguyen
bruno.nguyen2@example.com
Growth
Support
Brazil
$105,146.00
invited
Bruno Dubois
bruno.dubois3@example.com
Design
Manager
Nigeria
$86,538.00
active
Farid Haddad
farid.haddad4@example.com
Growth
Analyst
Brazil
$76,443.00
suspended
Jonas Yilmaz
jonas.yilmaz5@example.com
Core
Support
Vietnam
$129,812.00
active
Quyen Tanaka
quyen.tanaka6@example.com
Growth
Analyst
France
$72,011.00
suspended
Mai Nguyen
mai.nguyen7@example.com
Support
Analyst
Brazil
$83,226.00
invited
Bruno Novak
bruno.novak8@example.com
Support
Analyst
Poland
$71,507.00
active
<!-- The toolbar carries the chooser; place it yourself when you compose
     the chrome by hand. It lists only the columns the app declared, so the
     selection checkbox and the row grip never appear in it. -->
<Grid.Root {grid}>
  <Grid.Toolbar>
    <Grid.ColumnChooser />
  </Grid.Toolbar>
  <Grid.Viewport>
    <Grid.Header />
    <Grid.Body />
  </Grid.Viewport>
</Grid.Root>

Driving It From Code

Every gesture the header offers is a call you can make yourself, and each one emits its event, which is what a grid that persists its layout listens to. The badge below is the visible column order, read back from the grid.

Name | Email | Team | Role | Country | Salary
Email
Role
Country
Hoang Kowalski
hoang.kowalski1@example.com
Design
Manager
Poland
$127,691.00
Bruno Nguyen
bruno.nguyen2@example.com
Growth
Support
Brazil
$105,146.00
Bruno Dubois
bruno.dubois3@example.com
Design
Manager
Nigeria
$86,538.00
Farid Haddad
farid.haddad4@example.com
Growth
Analyst
Brazil
$76,443.00
Jonas Yilmaz
jonas.yilmaz5@example.com
Core
Support
Vietnam
$129,812.00
Quyen Tanaka
quyen.tanaka6@example.com
Growth
Analyst
France
$72,011.00
Mai Nguyen
mai.nguyen7@example.com
Support
Analyst
Brazil
$83,226.00
Bruno Novak
bruno.novak8@example.com
Support
Analyst
Poland
$71,507.00
8 rows
import { getColumnOps } from '@sv5ui/datagrid';

const ops = getColumnOps(grid);

ops?.setColumnWidth('name', 240);
ops?.autoSizeColumn('email');   // to the widest rendered cell
ops?.autoSizeColumns();         // every visible column at once
ops?.moveColumn('team', 0);     // to a visible index; returns where it landed
ops?.pinColumn('name', 'left'); // 'left' | 'right' | null
ops?.setColumnHidden('country', true);

// The same six through the flat api
grid.api.setColumnWidth?.('name', 240);
grid.api.pinColumn?.('name', 'left');

// Folding a header group comes through here too, so the header's toggle,
// the column menu and your own call all announce and emit alike.
ops?.toggleGroup('pay');
ops?.setGroupCollapsed('pay', true);

// Each one emits: columnResized, columnMoved, columnPinned,
// columnVisibilityChanged, columnGroupToggled.
grid.events.on('columnMoved', ({ columnId, toIndex }) => save(columnId, toIndex));

columnOps() Options

OptionDefault
resizetrue
reordertrue
pintrue
hidetrue
resizeStep16

Column Ops State

What getColumnOps(grid) exposes. The six methods are also on grid.api.

MemberDescription
setGroupCollapsed(id, on)Folds or unfolds a header group. The model settles whether the group may take that state at all
toggleGroup(id)The same door the header toggle and the column menu come through
setColumnWidth(id, width)Sets one column width, clamped to its min and max
autoSizeColumn(id)Fits the column to the widest rendered cell, header included
autoSizeColumns()The same for every visible column
moveColumn(id, index)Moves a column and returns the index it landed on
pinColumn(id, side)Pins to an edge, or unpins with null
setColumnHidden(id, hidden)Keeps the column in the model but out of the render
dragThe reorder in progress, for a custom indicator

Keyboard

On a focused header cell.

KeysAction
Shift + Arrow left or rightResizes the focused column by resizeStep
Alt + Arrow left or rightMoves the focused column, and follows it
Alt + Arrow downOpens the column menu
Double-click the resize handleAutosizes that column to its content