Skip to main content

Types

Reference for all shared types exported from @alaarab/ogrid-core. These types are also re-exported from all UI packages (@alaarab/ogrid-react-radix, @alaarab/ogrid-react-fluent, @alaarab/ogrid-react-material).

RowId

Unique identifier for a row. Used throughout the grid for row selection, tracking, and the getRowId callback.

type RowId = string | number;

FilterValue

A discriminated union representing a single filter value. Each variant has a type tag and a value field.

type FilterValue =
| { type: 'text'; value: string }
| { type: 'multiSelect'; value: string[] }
| { type: 'people'; value: UserLike }
| { type: 'date'; value: IDateFilterValue };
Filter Typetype Tagvalue ShapeExample
Text'text'string{ type: 'text', value: 'Alice' }
Multi-select'multiSelect'string[]{ type: 'multiSelect', value: ['Active', 'Pending'] }
People'people'UserLike{ type: 'people', value: { displayName: 'Alice', email: 'alice@example.com' } }
Date range'date'IDateFilterValue{ type: 'date', value: { from: '2024-01-01', to: '2024-12-31' } }

IDateFilterValue

A date range for date column filters. Both fields are optional ISO YYYY-MM-DD strings.

interface IDateFilterValue {
from?: string;
to?: string;
}
NameTypeDescription
fromstringStart date (inclusive). ISO YYYY-MM-DD format.
tostringEnd date (inclusive). ISO YYYY-MM-DD format.

IFilters

A record of active filters, keyed by field name. Each value is a FilterValue or undefined (when a filter has been cleared).

interface IFilters {
[field: string]: FilterValue | undefined;
}

Example

const filters: IFilters = {
name: { type: 'text', value: 'Alice' },
status: { type: 'multiSelect', value: ['Active', 'Pending'] },
owner: { type: 'people', value: { displayName: 'Bob', email: 'bob@example.com' } },
startDate: { type: 'date', value: { from: '2024-01-01' } },
department: undefined, // cleared filter
};

RowSelectionMode

Controls how row selection behaves in the grid.

type RowSelectionMode = 'none' | 'single' | 'multiple';
ValueDescription
'none'Row selection is disabled. No checkbox column is shown.
'single'Only one row can be selected at a time. Clicking a row replaces the previous selection.
'multiple'Multiple rows can be selected. A header checkbox toggles select/deselect all. Shift+click selects a range.

ISelectionRange

Describes a rectangular range of cells selected in the grid. Used internally by cell selection and passed to aggregation utilities.

interface ISelectionRange {
startRow: number;
startCol: number;
endRow: number;
endCol: number;
}
NameTypeDescription
startRownumberRow index where the selection began.
startColnumberColumn index where the selection began.
endRownumberRow index where the selection ended.
endColnumberColumn index where the selection ended.

The range is inclusive. startRow may be greater than endRow (and likewise for columns) when the user selects from bottom-right to top-left; the grid normalizes the range internally.

IActiveCell

Identifies the currently active (focused) cell in the grid.

interface IActiveCell {
rowIndex: number;
columnIndex: number;
}
NameTypeDescription
rowIndexnumberZero-based row index of the active cell.
columnIndexnumberZero-based column index of the active cell.

UserLike

Represents a person/user. Used by people type column filters and the searchPeople / getUserByEmail methods on IDataSource.

interface UserLike {
id?: string;
displayName: string;
email: string;
photo?: string;
}
NameTypeRequiredDescription
idstringNoUnique identifier for the user.
displayNamestringYesThe user's display name, shown in filter chips and people cells.
emailstringYesThe user's email address. Used as the filter value and for user resolution.
photostringNoURL to the user's profile photo. Displayed as an avatar in people filters.

IStatusBarProps

Configuration for the grid status bar, which displays counts and aggregation information at the bottom of the grid.

interface IStatusBarProps {
totalCount: number;
filteredCount?: number;
selectedCount?: number;
panels?: StatusBarPanel[];
aggregation?: {
sum: number;
avg: number;
min: number;
max: number;
count: number;
} | null;
}
NameTypeDefaultDescription
totalCountnumberRequiredTotal number of items in the data set.
filteredCountnumberundefinedNumber of items after filtering. When different from totalCount, the status bar shows "X of Y items".
selectedCountnumberundefinedNumber of selected rows. Shown when row selection is enabled.
panelsStatusBarPanel[]undefinedCustom status bar panels for additional content.
aggregation{ sum, avg, min, max, count } | nullundefinedAggregation values computed from the selected cell range. Displayed when the user selects a range containing numeric cells.

Aggregation Object

When cells are selected and contain numeric values, the status bar can display aggregation values.

NameTypeDescription
sumnumberSum of all numeric values in the selection.
avgnumberAverage of all numeric values in the selection.
minnumberMinimum numeric value in the selection.
maxnumberMaximum numeric value in the selection.
countnumberCount of numeric values in the selection.

Usage

Pass true for a default status bar, or an object for full control:

// Default status bar (shows item counts automatically)
<OGrid statusBar={true} ... />

// Custom status bar with aggregation
<OGrid
statusBar={{
totalCount: data.length,
filteredCount: filteredData.length,
selectedCount: selectedRows.size,
aggregation: { sum: 1500, avg: 375, min: 100, max: 600, count: 4 },
}}
...
/>

ISideBarDef

Configuration for the grid side bar panel.

interface ISideBarDef {
panels?: ('columns' | 'filters')[];
defaultPanel?: 'columns' | 'filters';
position?: 'left' | 'right';
}
NameTypeDefaultDescription
panels('columns' | 'filters')[]['columns', 'filters']Which panels to include in the side bar. 'columns' shows a column chooser. 'filters' shows filter controls.
defaultPanel'columns' | 'filters'undefinedWhich panel is open by default. When not set, the side bar starts collapsed.
position'left' | 'right''right'Which side of the grid the side bar appears on.

Usage

// Default side bar
<OGrid sideBar={true} ... />

// Custom side bar on the left, showing only column chooser
<OGrid
sideBar={{
panels: ['columns'],
position: 'left',
defaultPanel: 'columns',
}}
...
/>

IRowSelectionChangeEvent<T>

Event object passed to the onSelectionChange callback when row selection changes.

interface IRowSelectionChangeEvent<T> {
selectedRowIds: RowId[];
selectedItems: T[];
}
NameTypeDescription
selectedRowIdsRowId[]Array of IDs for all currently selected rows.
selectedItemsT[]Array of full row data objects for all currently selected rows.

Usage

<OGrid<Employee>
columns={columns}
data={data}
getRowId={(e) => e.id}
rowSelection="multiple"
onSelectionChange={(event) => {
console.log('Selected IDs:', event.selectedRowIds);
console.log('Selected items:', event.selectedItems);
}}
/>

IDataSource<T>

Server-side data source interface. When you pass a dataSource to OGrid instead of a data array, the grid calls these methods to fetch paginated data and filter options.

interface IDataSource<T> {
fetchPage(params: IFetchParams): Promise<IPageResult<T>>;
fetchFilterOptions?(field: string): Promise<string[]>;
searchPeople?(query: string): Promise<UserLike[]>;
getUserByEmail?(email: string): Promise<UserLike | undefined>;
}
MethodRequiredDescription
fetchPageYesFetch a page of data from the server. Called when the user changes page, page size, sort, or filters.
fetchFilterOptionsNoFetch filter options for a multi-select filter column. Called when a multi-select filter is opened.
searchPeopleNoSearch for people by name or email. Called when a user types in a people filter search box.
getUserByEmailNoResolve a user by email address. Called when restoring a saved people filter.

IFetchParams

Parameters passed to fetchPage:

interface IFetchParams {
page: number;
pageSize: number;
sort?: { field: string; direction: 'asc' | 'desc' };
filters: IFilters;
}
FieldTypeDescription
pagenumberCurrent page number (1-indexed).
pageSizenumberNumber of items per page.
sort{ field, direction }Active sort (field name + direction). Omit if no sort.
filtersIFiltersActive filters (field → FilterValue).

IPageResult<T>

Response shape from fetchPage:

interface IPageResult<T> {
items: T[];
totalCount: number;
}
FieldTypeDescription
itemsT[]Array of data items for the current page.
totalCountnumberTotal number of items across all pages (used for pagination).

Usage Example

import type { IDataSource, IFetchParams, IPageResult, UserLike } from '@alaarab/ogrid-react-radix';

interface Product {
id: number;
name: string;
category: string;
price: number;
}

const dataSource: IDataSource<Product> = {
async fetchPage(params: IFetchParams): Promise<IPageResult<Product>> {
// Build query string from params
const queryParams = new URLSearchParams({
page: params.page.toString(),
pageSize: params.pageSize.toString(),
sort: params.sort ? `${params.sort.field}:${params.sort.direction}` : '',
filters: JSON.stringify(params.filters),
});

const response = await fetch(`/api/products?${queryParams}`);
const data = await response.json();

return {
items: data.items,
totalCount: data.totalCount,
};
},

async fetchFilterOptions(field: string): Promise<string[]> {
const response = await fetch(`/api/products/filter-options/${field}`);
return response.json();
},

async searchPeople(query: string): Promise<UserLike[]> {
const response = await fetch(`/api/users/search?q=${encodeURIComponent(query)}`);
return response.json();
},

async getUserByEmail(email: string): Promise<UserLike | undefined> {
const response = await fetch(`/api/users/by-email/${encodeURIComponent(email)}`);
if (!response.ok) return undefined;
return response.json();
},
};

// Use with OGrid
<OGrid
dataSource={dataSource}
columns={columns}
getRowId={(item) => item.id}
/>

ICellEditorProps<T>

Props passed to custom cell editor components (React) or rendered by the inline cell editor.

interface ICellEditorProps<T> {
value: unknown;
onValueChange: (value: unknown) => void;
onCommit: () => void;
onCancel: () => void;
item: T;
column: IColumnDef<T>;
cellEditorParams?: CellEditorParams;
}
FieldTypeDescription
valueunknownCurrent cell value.
onValueChange(value: unknown) => voidCallback to update the value (doesn't commit yet).
onCommit() => voidCallback to commit the edit and close the editor.
onCancel() => voidCallback to cancel the edit and close the editor.
itemTFull row data object.
columnIColumnDef<T>Column definition.
cellEditorParamsCellEditorParamsOptional params passed to the editor (e.g., values for a select editor).

CellEditorParams

Parameters for built-in cell editors:

interface CellEditorParams {
values?: unknown[];
formatValue?: (value: unknown) => string;
}
FieldTypeDescription
valuesunknown[]Array of allowed values for select/richSelect editors.
formatValue(value: unknown) => stringCustom formatter for values in rich select editor.

Usage Example (React)

import type { ICellEditorProps } from '@alaarab/ogrid-react-radix';

interface Product {
id: number;
name: string;
category: string;
}

function CategoryEditor(props: ICellEditorProps<Product>) {
const { value, onValueChange, onCommit, onCancel, cellEditorParams } = props;

const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
onValueChange(e.target.value);
};

const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') onCommit();
if (e.key === 'Escape') onCancel();
};

return (
<select
value={value as string}
onChange={handleChange}
onKeyDown={handleKeyDown}
autoFocus
>
{cellEditorParams?.values?.map((v) => (
<option key={v as string} value={v as string}>
{v as string}
</option>
))}
</select>
);
}

// Use in column definition
const columns: IColumnDef<Product>[] = [
{
columnId: 'category',
name: 'Category',
editable: true,
cellEditor: CategoryEditor,
cellEditorParams: {
values: ['Electronics', 'Clothing', 'Books'],
},
},
];

ICellValueChangedEvent<T>

Event object passed to the onCellValueChanged callback when a cell value is committed after editing.

interface ICellValueChangedEvent<T> {
item: T;
columnId: string;
oldValue: unknown;
newValue: unknown;
rowIndex: number;
}
FieldTypeDescription
itemTFull row data object (with the new value already applied).
columnIdstringID of the column that was edited.
oldValueunknownValue before the edit.
newValueunknownValue after the edit.
rowIndexnumberZero-based row index.

Usage Example

<OGrid<Product>
columns={columns}
data={data}
getRowId={(item) => item.id}
editable={true}
onCellValueChanged={(event) => {
console.log(`Cell edited: ${event.columnId}`);
console.log(`Old value: ${event.oldValue}`);
console.log(`New value: ${event.newValue}`);
console.log('Updated item:', event.item);

// Sync changes to the server
updateProduct(event.item);
}}
/>

IGridColumnState

Column state object returned by IOGridApi.getColumnState() and accepted by applyColumnState(). All fields are JSON-serializable for persistence (e.g., localStorage).

interface IGridColumnState {
visibleColumns: string[];
sort?: { field: string; direction: 'asc' | 'desc' };
columnOrder?: string[];
columnWidths?: Record<string, number>;
filters?: IFilters;
pinnedColumns?: Record<string, 'left' | 'right'>;
}
FieldTypeDescription
visibleColumnsstring[]Array of visible column IDs.
sort{ field, direction }Active sort (field name + direction).
columnOrderstring[]Column display order (array of column IDs).
columnWidthsRecord<string, number>Column widths in pixels (column ID → width).
filtersIFiltersActive filters (field → FilterValue).
pinnedColumnsRecord<string, 'left' | 'right'>Pinned columns (column ID → position).

Usage Example

import { useRef } from 'react';
import { OGrid } from '@alaarab/ogrid-react-radix';
import type { IOGridApi } from '@alaarab/ogrid-react-radix';

function MyGrid() {
const apiRef = useRef<IOGridApi<Product>>(null);

const saveState = () => {
const state = apiRef.current?.getColumnState();
if (state) {
localStorage.setItem('gridState', JSON.stringify(state));
}
};

const restoreState = () => {
const saved = localStorage.getItem('gridState');
if (saved) {
const state = JSON.parse(saved);
apiRef.current?.applyColumnState(state);
}
};

return (
<>
<button onClick={saveState}>Save Grid State</button>
<button onClick={restoreState}>Restore Grid State</button>
<OGrid ref={apiRef} {...props} />
</>
);
}

IVirtualScrollConfig

Configuration for virtual scrolling (rendering only visible rows for large datasets).

interface IVirtualScrollConfig {
enabled?: boolean;
rowHeight?: number;
overscan?: number;
}
FieldTypeDefaultDescription
enabledbooleanfalseEnable virtual scrolling.
rowHeightnumberRequired when enabledFixed row height in pixels. All rows must have the same height.
overscannumber5Number of extra rows to render above/below the visible area (for smoother scrolling).

Usage Example

<OGrid
data={largeDataset} // 10,000+ rows
columns={columns}
getRowId={(item) => item.id}
virtualScroll={{
enabled: true,
rowHeight: 40,
overscan: 10,
}}
/>

Type Imports

All types can be imported from any OGrid package:

// From the core package (useful in shared code)
import type {
RowId,
FilterValue,
IFilters,
RowSelectionMode,
ISelectionRange,
IActiveCell,
UserLike,
IStatusBarProps,
ISideBarDef,
IRowSelectionChangeEvent,
IColumnDef,
IColumnGroupDef,
IDataSource,
IOGridApi,
IOGridProps,
ICellEditorProps,
ICellValueChangedEvent,
IGridColumnState,
IVirtualScrollConfig,
IFetchParams,
IPageResult,
CellEditorParams,
} from '@alaarab/ogrid-react-radix';

// From UI packages (re-exports everything from core)
import type { IColumnDef, IOGridApi } from '@alaarab/ogrid-react-radix';
import type { IColumnDef, IOGridApi } from '@alaarab/ogrid-react-fluent';
import type { IColumnDef, IOGridApi } from '@alaarab/ogrid-react-material';