Skip to content

Commit 9bdf9e0

Browse files
committed
Expand styling and customization docs
1 parent fc5d010 commit 9bdf9e0

File tree

4 files changed

+300
-11
lines changed

4 files changed

+300
-11
lines changed

README.md

Lines changed: 292 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,299 @@ function App() {
120120
}
121121
```
122122

123-
## Theming
123+
## Styling and Customization
124124

125-
Set `--rdg-color-scheme: light/dark` at the `:root` to control the color theme. The light or dark themes can be enforced using the `rdg-light` or `rdg-dark` classes.
125+
The DataGrid provides multiple ways to customize its appearance and behavior.
126+
127+
### Light/Dark Themes
128+
129+
The DataGrid supports both light and dark color schemes out of the box using CSS's `light-dark()` function. The theme automatically adapts based on the user's system preference when `color-scheme: light dark;` is set.
130+
131+
To enforce a specific theme, we recommend setting the standard `color-scheme` CSS property on the `:root`:
132+
133+
```css
134+
:root {
135+
color-scheme: light; /* or 'dark', or 'light dark' for auto */
136+
}
137+
```
138+
139+
Alternatively, you can add the `rdg-light` or `rdg-dark` class to individual grids:
140+
141+
```tsx
142+
// Force light theme
143+
<DataGrid className="rdg-light" columns={columns} rows={rows} />
144+
145+
// Force dark theme
146+
<DataGrid className="rdg-dark" columns={columns} rows={rows} />
147+
```
148+
149+
### CSS Variables
150+
151+
The DataGrid supports the following CSS variables for customization:
152+
153+
```css
154+
.rdg {
155+
/* Selection */
156+
--rdg-selection-width: 2px;
157+
--rdg-selection-color: hsl(207, 75%, 66%);
158+
159+
/* Typography */
160+
--rdg-font-size: 14px;
161+
162+
/* Colors (using light-dark() for automatic theme switching) */
163+
--rdg-color: light-dark(#000, #ddd);
164+
--rdg-background-color: light-dark(hsl(0deg 0% 100%), hsl(0deg 0% 13%));
165+
166+
/* Header */
167+
--rdg-header-background-color: light-dark(hsl(0deg 0% 97.5%), hsl(0deg 0% 10.5%));
168+
--rdg-header-draggable-background-color: light-dark(hsl(0deg 0% 90.5%), hsl(0deg 0% 17.5%));
169+
170+
/* Rows */
171+
--rdg-row-hover-background-color: light-dark(hsl(0deg 0% 96%), hsl(0deg 0% 9%));
172+
--rdg-row-selected-background-color: light-dark(hsl(207deg 76% 92%), hsl(207deg 76% 42%));
173+
--rdg-row-selected-hover-background-color: light-dark(hsl(207deg 76% 88%), hsl(207deg 76% 38%));
174+
175+
/* Borders */
176+
--rdg-border-width: 1px;
177+
--rdg-border-color: light-dark(#ddd, #444);
178+
--rdg-summary-border-width: calc(var(--rdg-border-width) * 2);
179+
--rdg-summary-border-color: light-dark(#aaa, #555);
180+
181+
/* Frozen columns */
182+
--rdg-cell-frozen-box-shadow: 2px 0 5px -2px rgba(136, 136, 136, 0.3);
183+
184+
/* Checkboxes */
185+
--rdg-checkbox-focus-color: hsl(207deg 100% 69%);
186+
}
187+
```
188+
189+
Example of customizing colors:
190+
191+
```css
192+
.my-custom-grid {
193+
--rdg-background-color: #f0f0f0;
194+
--rdg-selection-color: #ff6b6b;
195+
--rdg-font-size: 16px;
196+
}
197+
```
198+
199+
```tsx
200+
<DataGrid className="my-custom-grid" columns={columns} rows={rows} />
201+
```
202+
203+
### Standard Props
204+
205+
The DataGrid accepts standard `className` and `style` props:
206+
207+
```tsx
208+
<DataGrid
209+
columns={columns}
210+
rows={rows}
211+
className="my-grid custom-theme"
212+
style={{ height: '600px', border: '2px solid navy' }}
213+
/>
214+
```
215+
216+
### Row and Cell Styling
217+
218+
#### Row Heights
219+
220+
Control row heights using the [`rowHeight`](#rowheight-maybenumber--row-r--number) prop:
221+
222+
```tsx
223+
// Fixed height for all rows
224+
<DataGrid columns={columns} rows={rows} rowHeight={50} />
225+
226+
// Dynamic height per row
227+
<DataGrid
228+
columns={columns}
229+
rows={rows}
230+
rowHeight={(row) => row.isExpanded ? 100 : 35}
231+
/>
232+
```
233+
234+
You can also customize header and summary row heights:
235+
236+
```tsx
237+
<DataGrid
238+
columns={columns}
239+
rows={rows}
240+
rowHeight={35}
241+
headerRowHeight={45}
242+
summaryRowHeight={40}
243+
topSummaryRows={topSummaryRows}
244+
/>
245+
```
246+
247+
#### Row Classes
248+
249+
Apply custom CSS classes to rows using the [`rowClass`](#rowclass-mayberow-r-rowidx-number--maybestring) prop:
250+
251+
```tsx
252+
<DataGrid
253+
columns={columns}
254+
rows={rows}
255+
rowClass={(row, rowIdx) => {
256+
if (row.status === 'error') return 'row-error';
257+
if (rowIdx % 2 === 0) return 'row-even';
258+
return 'row-odd';
259+
}}
260+
/>
261+
```
262+
263+
```css
264+
.row-error {
265+
background-color: #fee;
266+
color: #c00;
267+
}
268+
269+
.row-even {
270+
background-color: #f9f9f9;
271+
}
272+
```
273+
274+
For header rows, use the [`headerRowClass`](#headerrowclass-maybestring) prop:
275+
276+
```tsx
277+
<DataGrid columns={columns} rows={rows} headerRowClass="sticky-header" />
278+
```
279+
280+
#### Cell Classes
281+
282+
Apply custom CSS classes to cells using the `cellClass` property in column definitions:
283+
284+
```tsx
285+
const columns: Column<Row>[] = [
286+
{
287+
key: 'status',
288+
name: 'Status',
289+
cellClass: (row) => `status-${row.status.toLowerCase()}`
290+
},
291+
{
292+
key: 'price',
293+
name: 'Price',
294+
cellClass: 'text-right' // Static class
295+
}
296+
];
297+
```
298+
299+
```css
300+
.status-active {
301+
color: green;
302+
font-weight: bold;
303+
}
304+
305+
.status-inactive {
306+
color: gray;
307+
}
308+
309+
.text-right {
310+
text-align: right;
311+
}
312+
```
313+
314+
You can also use `headerCellClass` and `summaryCellClass` for header and summary cells respectively.
315+
316+
#### Column Widths
317+
318+
Control column widths using the `width`, `minWidth`, and `maxWidth` properties:
319+
320+
```tsx
321+
const columns: Column<Row>[] = [
322+
{
323+
key: 'id',
324+
name: 'ID',
325+
width: 80, // Fixed width
326+
resizable: false
327+
},
328+
{
329+
key: 'name',
330+
name: 'Name',
331+
width: '30%', // Percentage width
332+
minWidth: 100,
333+
maxWidth: 400
334+
},
335+
{
336+
key: 'description',
337+
name: 'Description'
338+
// No width specified - automatically sized
339+
}
340+
];
341+
```
342+
343+
Enable column resizing by setting `resizable: true` on individual columns or use [`defaultColumnOptions`](#defaultcolumnoptions-maybedefaultcolumnoptionsr-sr) to apply it to all columns:
344+
345+
```tsx
346+
<DataGrid
347+
columns={columns}
348+
rows={rows}
349+
defaultColumnOptions={{
350+
resizable: true,
351+
sortable: true
352+
}}
353+
/>
354+
```
355+
356+
### Custom Renderers
357+
358+
Replace default components with custom implementations using the [`renderers`](#renderers-mayberendererstrow-tsummaryrow) prop:
359+
360+
```tsx
361+
const customRenderers = {
362+
// Custom row component
363+
renderRow(key, props) {
364+
return <CustomRow key={key} {...props} />;
365+
},
366+
367+
// Custom cell component
368+
renderCell(key, props) {
369+
return <CustomCell key={key} {...props} />;
370+
},
371+
372+
// Custom checkbox component
373+
renderCheckbox(props) {
374+
return <CustomCheckbox {...props} />;
375+
},
376+
377+
// Custom sort status indicator
378+
renderSortStatus(props) {
379+
return <CustomSortIcon {...props} />;
380+
},
381+
382+
// Custom empty state
383+
noRowsFallback: <div>No data available</div>
384+
};
385+
386+
<DataGrid columns={columns} rows={rows} renderers={customRenderers} />;
387+
```
388+
389+
Columns can also have custom renderers:
390+
391+
```tsx
392+
const columns: Column<Row>[] = [
393+
{
394+
key: 'avatar',
395+
name: 'Avatar',
396+
renderCell(props) {
397+
return <img src={props.row.avatarUrl} alt={props.row.name} />;
398+
}
399+
},
400+
{
401+
key: 'status',
402+
name: 'Status',
403+
renderHeaderCell(props) {
404+
return (
405+
<div>
406+
<strong>{props.column.name}</strong>
407+
<InfoIcon />
408+
</div>
409+
);
410+
}
411+
}
412+
];
413+
```
414+
415+
See the [Renderers section](#renderers-mayberendererstrow-tsummaryrow) for full type definitions and examples.
126416

127417
## API Reference
128418

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"typecheck": "tsc --build"
5151
},
5252
"devDependencies": {
53-
"@biomejs/biome": "2.3.8",
53+
"@biomejs/biome": "2.3.10",
5454
"@eslint-react/eslint-plugin": "^2.3.12",
5555
"@eslint/markdown": "^7.5.1",
5656
"@faker-js/faker": "^10.0.0",
@@ -82,7 +82,7 @@
8282
"react": "^19.2.1",
8383
"react-dom": "^19.2.1",
8484
"rolldown": "^1.0.0-beta.51",
85-
"rolldown-plugin-dts": "^0.18.0",
85+
"rolldown-plugin-dts": "^0.19.1",
8686
"typescript": "~5.9.2",
8787
"vite": "npm:rolldown-vite@^7.2.5",
8888
"vitest": "^4.0.15",

src/style/core.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,13 @@ const root = css`
3131
--rdg-checkbox-focus-color: hsl(207deg 100% 69%);
3232
3333
&.rdg-dark {
34-
--rdg-color-scheme: dark;
34+
color-scheme: dark;
3535
}
3636
3737
&.rdg-light {
38-
--rdg-color-scheme: light;
38+
color-scheme: light;
3939
}
4040
41-
color-scheme: var(--rdg-color-scheme, light dark);
42-
4341
&:dir(rtl) {
4442
--rdg-cell-frozen-box-shadow: -2px 0 5px -2px rgba(136, 136, 136, 0.3);
4543
}

website/root.css

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ body {
66
}
77

88
:root {
9+
color-scheme: light dark;
10+
911
&:has([value='light']:checked) {
10-
--rdg-color-scheme: light;
12+
color-scheme: light;
1113
}
1214

1315
&:has([value='dark']:checked) {
14-
--rdg-color-scheme: dark;
16+
color-scheme: dark;
1517
}
1618
}
1719

1820
body {
19-
color-scheme: var(--rdg-color-scheme, light dark);
2021
background-color: light-dark(#fff, hsl(0deg 0% 10%));
2122
color: light-dark(#111, #fff);
2223
}

0 commit comments

Comments
 (0)