Quick Start
Build a sortable, filterable, editable data grid in under 50 lines.
Install
- React
- Angular
- Vue
- Vanilla JS
- Radix (Default)
- Fluent UI
- Material UI
npm install @alaarab/ogrid-react-radix
npm install @alaarab/ogrid-react-fluent @fluentui/react-components
npm install @alaarab/ogrid-react-material @mui/material @emotion/react @emotion/styled
- Angular Material
- PrimeNG
npm install @alaarab/ogrid-angular-material @angular/material @angular/cdk
npm install @alaarab/ogrid-angular-primeng primeng
- Vuetify
- PrimeVue
npm install @alaarab/ogrid-vue-vuetify vuetify
npm install @alaarab/ogrid-vue-primevue primevue
npm install @alaarab/ogrid-js
Full Example
- React
- Angular
- Vue
- Vanilla JS
import { OGrid, type IColumnDef } from '@alaarab/ogrid-react-radix';
interface Employee {
id: number;
name: string;
department: string;
salary: number;
}
const data: Employee[] = [
{ id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000 },
{ id: 2, name: 'Bob Smith', department: 'Marketing', salary: 72000 },
{ id: 3, name: 'Carol Williams', department: 'Engineering', salary: 110000 },
{ id: 4, name: 'David Brown', department: 'Sales', salary: 68000 },
{ id: 5, name: 'Eva Martinez', department: 'Marketing', salary: 78000 },
];
const columns: IColumnDef<Employee>[] = [
{ columnId: 'name', name: 'Name', sortable: true },
{
columnId: 'department',
name: 'Department',
sortable: true,
filterable: { type: 'multiSelect', options: ['Engineering', 'Marketing', 'Sales'] },
},
{
columnId: 'salary',
name: 'Salary',
type: 'numeric',
sortable: true,
editable: true,
valueFormatter: (value) =>
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value as number),
},
];
export default function App() {
return (
<OGrid<Employee>
columns={columns}
data={data}
getRowId={(row) => row.id}
defaultPageSize={10}
defaultSortBy="name"
statusBar
aria-label="Employee directory"
/>
);
}
Switching UI libraries
The OGrid component has the same props across all React UI packages. To switch, just change the import:
- Radix (lightweight, default):
from '@alaarab/ogrid-react-radix' - Fluent UI (Microsoft 365 / SPFx):
from '@alaarab/ogrid-react-fluent'— wrap in<FluentProvider> - Material UI (MUI v7):
from '@alaarab/ogrid-react-material'— wrap in<ThemeProvider>
import { Component } from '@angular/core';
import { OGridComponent, type IColumnDef } from '@alaarab/ogrid-angular-material';
interface Employee {
id: number;
name: string;
department: string;
salary: number;
}
@Component({
standalone: true,
imports: [OGridComponent],
template: `<ogrid [props]="gridProps" />`
})
export class EmployeeGridComponent {
private readonly data: Employee[] = [
{ id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000 },
{ id: 2, name: 'Bob Smith', department: 'Marketing', salary: 72000 },
{ id: 3, name: 'Carol Williams', department: 'Engineering', salary: 110000 },
{ id: 4, name: 'David Brown', department: 'Sales', salary: 68000 },
{ id: 5, name: 'Eva Martinez', department: 'Marketing', salary: 78000 },
];
private readonly columns: IColumnDef<Employee>[] = [
{ columnId: 'name', name: 'Name', sortable: true },
{
columnId: 'department', name: 'Department', sortable: true,
filterable: { type: 'multiSelect', options: ['Engineering', 'Marketing', 'Sales'] },
},
{
columnId: 'salary', name: 'Salary', type: 'numeric', sortable: true, editable: true,
valueFormatter: (value) =>
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value as number),
},
];
gridProps = {
columns: this.columns,
data: this.data,
getRowId: (row: Employee) => row.id,
defaultPageSize: 10,
defaultSortBy: 'name',
statusBar: true,
};
}
Switching UI libraries
Same component API across Angular packages. To switch, just change the import:
- Angular Material:
from '@alaarab/ogrid-angular-material' - PrimeNG:
from '@alaarab/ogrid-angular-primeng'
All components are standalone — no NgModule required.
<script setup lang="ts">
import { OGrid, type IColumnDef } from '@alaarab/ogrid-vue-vuetify';
interface Employee {
id: number;
name: string;
department: string;
salary: number;
}
const data: Employee[] = [
{ id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000 },
{ id: 2, name: 'Bob Smith', department: 'Marketing', salary: 72000 },
{ id: 3, name: 'Carol Williams', department: 'Engineering', salary: 110000 },
{ id: 4, name: 'David Brown', department: 'Sales', salary: 68000 },
{ id: 5, name: 'Eva Martinez', department: 'Marketing', salary: 78000 },
];
const columns: IColumnDef<Employee>[] = [
{ columnId: 'name', name: 'Name', sortable: true },
{
columnId: 'department', name: 'Department', sortable: true,
filterable: { type: 'multiSelect', options: ['Engineering', 'Marketing', 'Sales'] },
},
{
columnId: 'salary', name: 'Salary', type: 'numeric', sortable: true, editable: true,
valueFormatter: (value) =>
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value as number),
},
];
const gridProps = {
columns,
data,
getRowId: (row: Employee) => row.id,
defaultPageSize: 10,
defaultSortBy: 'name',
statusBar: true,
};
</script>
<template>
<OGrid :gridProps="gridProps" />
</template>
Switching UI libraries
Same component API across Vue packages. To switch, just change the import:
- Vuetify:
from '@alaarab/ogrid-vue-vuetify'— wrap in<v-app>for theming - PrimeVue:
from '@alaarab/ogrid-vue-primevue'
import { OGrid } from '@alaarab/ogrid-js';
import '@alaarab/ogrid-js/styles';
const grid = new OGrid(document.getElementById('grid'), {
columns: [
{ columnId: 'name', name: 'Name', sortable: true },
{
columnId: 'department',
name: 'Department',
sortable: true,
filterable: { type: 'multiSelect', options: ['Engineering', 'Marketing', 'Sales'] },
},
{
columnId: 'salary',
name: 'Salary',
type: 'numeric',
sortable: true,
editable: true,
valueFormatter: (value) =>
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value),
},
],
data: [
{ id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000 },
{ id: 2, name: 'Bob Smith', department: 'Marketing', salary: 72000 },
{ id: 3, name: 'Carol Williams', department: 'Engineering', salary: 110000 },
{ id: 4, name: 'David Brown', department: 'Sales', salary: 68000 },
{ id: 5, name: 'Eva Martinez', department: 'Marketing', salary: 78000 },
],
getRowId: (row) => row.id,
pageSize: 10,
editable: true,
});
tip
The JS package uses a class-based imperative API. See the Vanilla JS guide for the full API including events, grid methods, and theming.
What You Get
With just this code:
- Sorting -- click column headers to sort ascending/descending
- Filtering -- click the filter icon on Department to filter by value
- Inline editing -- double-click any salary cell to edit
- Numeric formatting --
type: 'numeric'right-aligns;valueFormatterdisplays currency - Pagination, keyboard nav, cell selection, status bar -- all built in
Key Concepts
| Concept | Description |
|---|---|
IColumnDef<T> | Column config. columnId matches a key on T (or use valueGetter). |
getRowId | Returns a unique string | number per row for selection, editing, and re-rendering. |
layoutMode | 'fill' (default) fills container; 'content' sizes to content. |
Using the Grid API
- React
- Angular
- Vue
- Vanilla JS
import { useRef } from 'react';
import { OGrid, type IOGridApi } from '@alaarab/ogrid-react-radix';
function App() {
const gridRef = useRef<IOGridApi<Employee>>(null);
return (
<>
<button onClick={() => console.log(gridRef.current?.getColumnState())}>
Log State
</button>
<OGrid<Employee> ref={gridRef} columns={columns} data={data} getRowId={(row) => row.id} />
</>
);
}
import { Component, ViewChild } from '@angular/core';
import { OGridComponent, OGridService } from '@alaarab/ogrid-angular-material';
@Component({
standalone: true,
imports: [OGridComponent],
template: `
<button (click)="logState()">Log State</button>
<ogrid [props]="gridProps" />
`
})
export class AppComponent {
constructor(private gridService: OGridService) {}
logState() {
console.log(this.gridService.getColumnState());
}
gridProps = { columns, data, getRowId: (row: any) => row.id };
}
<script setup lang="ts">
import { ref } from 'vue';
import { OGrid, useOGrid } from '@alaarab/ogrid-vue-vuetify';
const { getColumnState } = useOGrid({ columns, data, getRowId: (row) => row.id });
function logState() {
console.log(getColumnState());
}
</script>
<template>
<button @click="logState">Log State</button>
<OGrid :gridProps="{ columns, data, getRowId: (row) => row.id }" />
</template>
import { OGrid } from '@alaarab/ogrid-js';
const grid = new OGrid(document.getElementById('grid'), {
columns, data, getRowId: (row) => row.id,
});
// Programmatic control
const api = grid.getApi();
console.log(api.getColumnState());
api.setRowData(newData);
// Cleanup
grid.destroy();
Next Steps
- Sorting, Filtering, Editing -- core features
- Grid API -- imperative methods
- Column Definitions -- all column options
- Controlled vs Uncontrolled -- managing state externally
- Server-Side Data -- connect to REST APIs or GraphQL