Appearance
Pinning, moving & sizing
The demo has pinned columns on both sides. Drag the header border to resize a column (double click to autosize), drag a header to move a column, open the column menu to pin, hide or autosize columns and toggle columns with the checkboxes.
Source
vue
<template>
<div class="demo">
<div class="demo-toolbar">
<label v-for="col in toggleColumns" :key="col.id">
<input
type="checkbox"
:checked="visible[col.id] !== false"
@change="api?.setColumnVisible(col.id, ($event.target as HTMLInputElement).checked)"
/>
{{ col.text }}
</label>
<button @click="api?.autosizeColumns()">Autosize</button>
<button @click="api?.resetColumnState()">Reset</button>
</div>
<Datagrid
:columns="columns"
:rows="rows"
:options="options"
@ready="api = $event"
@state-change="onStateChange"
/>
</div>
</template>
<script setup lang="ts">
import { ref, shallowRef } from "vue";
import { Datagrid, type ColumnConfig, type Core, type GridOptions, type GridState } from "@datagrid/vue-ui";
import { createEmployees, type Employee } from "./data";
const rows = createEmployees(200);
const api = shallowRef<Core>();
const columns: Array<ColumnConfig<Employee>> = [
{ field: "id", text: "ID", type: "number", width: 70, pinned: "left" },
{ field: "firstName", text: "First name", pinned: "left" },
{ field: "lastName", text: "Last name" },
{ field: "email", text: "Email", width: 260 },
{ field: "department", text: "Department" },
{ field: "role", text: "Role" },
{ field: "city", text: "City" },
{ field: "country", text: "Country", visible: false },
{ field: "startDate", text: "Start date", type: "date" },
{ field: "salary", text: "Salary", type: "number", pinned: "right" },
];
// columns which can be toggled with the checkboxes
const toggleColumns = [
{ id: "email", text: "Email" },
{ id: "role", text: "Role" },
{ id: "city", text: "City" },
{ id: "country", text: "Country" },
{ id: "startDate", text: "Start date" },
];
const options: GridOptions<Employee> = {
columnMenu: true,
defaultColumn: { sortable: true, resizeable: true, moveable: true, width: 130 },
};
// the visibility is read from the column state, so changes in the column menu are reflected too
const visible = ref<Record<string, boolean>>({ country: false });
function onStateChange(state: GridState) {
visible.value = Object.fromEntries(state.columns.map((col) => [col.id, col.visible]));
}
</script>tsx
import { useState } from "react";
import { Datagrid, type ColumnConfig, type Core, type GridOptions, type GridState } from "@datagrid/react-ui";
import { createEmployees, type Employee } from "../data";
const rows = createEmployees(200);
const columns: Array<ColumnConfig<Employee>> = [
{ field: "id", text: "ID", type: "number", width: 70, pinned: "left" },
{ field: "firstName", text: "First name", pinned: "left" },
{ field: "lastName", text: "Last name" },
{ field: "email", text: "Email", width: 260 },
{ field: "department", text: "Department" },
{ field: "role", text: "Role" },
{ field: "city", text: "City" },
{ field: "country", text: "Country", visible: false },
{ field: "startDate", text: "Start date", type: "date" },
{ field: "salary", text: "Salary", type: "number", pinned: "right" },
];
// columns which can be toggled with the checkboxes
const toggleColumns = [
{ id: "email", text: "Email" },
{ id: "role", text: "Role" },
{ id: "city", text: "City" },
{ id: "country", text: "Country" },
{ id: "startDate", text: "Start date" },
];
const options: GridOptions<Employee> = {
columnMenu: true,
defaultColumn: { sortable: true, resizeable: true, moveable: true, width: 130 },
};
export default function ColumnLayout() {
const [api, setApi] = useState<Core>();
// the visibility is read from the column state, so changes in the column menu are reflected too
const [visible, setVisible] = useState<Record<string, boolean>>({ country: false });
function onStateChange(state: GridState) {
setVisible(Object.fromEntries(state.columns.map((col) => [col.id, col.visible])));
}
return (
<div className="demo">
<div className="demo-toolbar">
{toggleColumns.map((col) => (
<label key={col.id}>
<input
type="checkbox"
checked={visible[col.id] !== false}
onChange={(e) => api?.setColumnVisible(col.id, e.target.checked)}
/>{" "}
{col.text}
</label>
))}
<button onClick={() => api?.autosizeColumns()}>Autosize</button>
<button onClick={() => api?.resetColumnState()}>Reset</button>
</div>
<Datagrid columns={columns} rows={rows} options={options} onReady={setApi} onStateChange={onStateChange} />
</div>
);
}Width
| Property | Description |
|---|---|
width | Width in pixels (default 100). |
minWidth, maxWidth | Limits for resizing and autosizing. |
flex | The column takes a share of the free space. Two columns with flex: 1 and flex: 2 get one and two thirds of the remaining width. |
autosize | The width is calculated from the content of the first rows and the header when the grid is initialized. |
autosizeAdjust | (column, { headerWidth, contentWidth }) => width to adjust the calculated width. |
Users can resize columns with resizeable: true by dragging the right border of the header. A double click on the border autosizes the column.
ts
// API
api.setColumnWidth("name", 200);
await api.autosizeColumns(["name", "city"]); // or api.autosizeColumns() for all columns
api.sizeColumnsToFit(); // recalculates the flex columnsPinning
Pinned columns stay visible while scrolling horizontally:
ts
{ field: "id", pinned: "left" },
{ field: "actions", pinned: "right" },The pinning can be changed with the column menu or the API:
ts
api.setColumnPinned("salary", "left");
api.setColumnPinned("salary", undefined); // unpinChildren of a column group always have the pinning of the group.
Moving
Columns with moveable: true can be dragged to another position within their pinned area. Press Escape while dragging to cancel.
ts
api.moveColumn("salary", 0); // index relative to the siblingsVisibility
ts
{ field: "internalId", visible: false }
api.hideColumn("city");
api.showColumn("city");
api.setColumnVisible("city", false);
api.toggleColumnVisibility("city");The column menu contains a column chooser to show and hide columns.
Column menu
The column menu is opened with the button in the header. It offers sorting, pinning, autosizing, grouping, hiding and the column chooser. It is enabled for all columns with the grid option columnMenu: true or per column with menu: true.
Saving the column layout
The column layout (order, width, visibility, pinning) is part of the grid state:
ts
const columnState = api.getColumnState();
localStorage.setItem("columns", JSON.stringify(columnState));
api.setColumnState(JSON.parse(localStorage.getItem("columns")));
api.resetColumnState(); // back to the column definitions