Theming & CSS Variables
OGrid is designed to inherit your application's design system. Each UI package integrates with its framework's theming mechanism, and the core grid exposes CSS variables and props for fine-grained control.
CSS Variables
OGrid exposes CSS custom properties that you can override to change the grid's appearance globally or per-instance.
| Variable | Default | Description |
|---|---|---|
--ogrid-selection | #217346 | Cell selection highlight color (active cell border, range background) |
Override globally:
:root {
--ogrid-selection: #0066cc;
}
Or scope it to a specific grid instance using the className prop:
.my-grid {
--ogrid-selection: #8b5cf6;
}
<OGrid className="my-grid" columns={columns} data={data} getRowId={(item) => item.id} />
Framework Theming
Each UI package inherits styles from its framework's theme system. OGrid does not fight your theme -- it builds on top of it.
Radix UI (@alaarab/ogrid-react-radix)
Radix is the lightest implementation. It uses CSS Modules (.module.scss) for all grid styles. Override styles with standard CSS specificity or by targeting the grid's class names.
Fluent UI (@alaarab/ogrid-react-fluent)
The Fluent implementation renders with Fluent UI v9 components, which inherit from FluentProvider. Wrap your app in a FluentProvider with your theme:
import { FluentProvider, webLightTheme } from '@fluentui/react-components';
import { OGrid } from '@alaarab/ogrid-react-fluent';
function App() {
return (
<FluentProvider theme={webLightTheme}>
<OGrid columns={columns} data={data} getRowId={(item) => item.id} />
</FluentProvider>
);
}
Fluent also uses CSS Modules for grid-specific styles (cell selection, fill handle, etc.).
Layout Mode
The layoutMode prop controls how the grid sizes itself:
| Mode | Behavior |
|---|---|
'fill' (default) | Grid stretches to fill its parent container. The parent must have a defined height. |
'content' | Grid sizes itself based on content. Width fits columns; height fits rows. |
{/* Fill parent container */}
<div style={{ height: 600 }}>
<OGrid layoutMode="fill" columns={columns} data={data} getRowId={(item) => item.id} />
</div>
{/* Size to content */}
<OGrid layoutMode="content" columns={columns} data={data} getRowId={(item) => item.id} />
When using layoutMode="fill", make sure the grid's parent has a defined height (explicit px/vh/%, or flex layout). Without it, the grid will collapse to zero height.
Suppress Horizontal Scroll
To prevent horizontal scrolling (useful when all columns fit the viewport), set suppressHorizontalScroll:
<OGrid suppressHorizontalScroll columns={columns} data={data} getRowId={(item) => item.id} />
This sets overflow-x: hidden on the grid's scroll container.
Per-Cell Styles
Use cellStyle on a column definition to apply inline styles to individual cells. It accepts a static style object or a function for conditional styling:
Static Style
const columns = [
{
columnId: 'amount',
name: 'Amount',
type: 'numeric' as const,
cellStyle: { fontWeight: 600 },
},
];
Dynamic Style (Per-Row)
const columns = [
{
columnId: 'status',
name: 'Status',
cellStyle: (item) => ({
color: item.status === 'Active' ? '#16a34a' : '#dc2626',
fontWeight: 600,
}),
},
];
Numeric Column Alignment
Set type: 'numeric' on a column to right-align cell content automatically:
{
columnId: 'price',
name: 'Price',
type: 'numeric',
valueFormatter: (value) => `$${Number(value).toFixed(2)}`,
}
Custom Wrapper Class
The className prop adds a CSS class to the grid's outermost wrapper element. Use it for scoped styling:
<OGrid className="dashboard-grid" columns={columns} data={data} getRowId={(item) => item.id} />
.dashboard-grid {
border: 1px solid #e5e7eb;
border-radius: 8px;
overflow: hidden;
}
Column Width Control
Control column widths through the column definition:
| Prop | Description |
|---|---|
minWidth | Minimum column width in pixels |
defaultWidth | Initial column width in pixels |
idealWidth | Preferred width (used for auto-sizing) |
{
columnId: 'description',
name: 'Description',
minWidth: 150,
defaultWidth: 300,
}
Users can resize columns by dragging the column border. Listen for resize events with onColumnResized:
<OGrid
columns={columns}
data={data}
getRowId={(item) => item.id}
onColumnResized={(columnId, width) => {
localStorage.setItem(`col-width-${columnId}`, String(width));
}}
/>
Theme presets (new in 2.9)
Instead of mapping --ogrid-* variables to your design system one-by-one,
import a pre-built preset that bridges every token at once. Currently the
shadcn/Tailwind v4 preset ships with @alaarab/ogrid-react-radix:
import "@alaarab/ogrid-react-radix/styles/index.css";
import "@alaarab/ogrid-react-radix/styles/preset-shadcn.css";
The preset maps --ogrid-bg → var(--card), --ogrid-fg → var(--card-foreground),
--ogrid-header-bg → var(--muted), --ogrid-primary → var(--primary),
--ogrid-accent → var(--ring), --ogrid-border → var(--border),
--ogrid-radius → var(--radius), --ogrid-font → var(--font-sans), and
derived states (--ogrid-selected-row-bg, --ogrid-range-bg, etc.) via
color-mix(in oklch, var(--ring) 12%, transparent) so they auto-tint to
your primary/ring hue.
Both light and dark modes follow your shadcn theme automatically — no
hand-authored [data-theme="dark"] override blocks needed. The .dark
class on <html> (Tailwind v3+/shadcn convention) is fully supported.
New theming tokens (2.9)
In addition to the colors documented above, 2.8.0 added a radius/font/ring
scale that preset-shadcn.css bridges automatically:
| Variable | Default | Description |
|---|---|---|
--ogrid-radius | 6px | Base corner radius — buttons, inputs, popovers |
--ogrid-radius-sm | calc(--ogrid-radius * 0.6) | Tighter — checkboxes, tags |
--ogrid-radius-lg | calc(--ogrid-radius * 1.4) | Looser — cards, dialogs |
--ogrid-radius-xl | calc(--ogrid-radius * 1.8) | Largest — hero surfaces |
--ogrid-radius-full | 9999px | Pills, dots |
--ogrid-font | inherit | Font family for grid chrome |
--ogrid-font-size | 13px | Base body font-size |
--ogrid-ring | var(--ogrid-accent) | Focus ring color |
Override --ogrid-radius once and every corner in OGrid scales (sm/lg/xl
are calc()'d from the base).
Dark mode signals
OGrid honors three dark-mode activation signals:
prefers-color-scheme: dark— system preference (auto)[data-theme="dark"]on any ancestor (explicit).darkon any ancestor — Tailwind v3+/shadcn convention (explicit)
Opt out of auto-dark on a deliberate-light-mode app by setting
[data-theme="light"] or .light on <html>.