or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

components.mdcore-grid.mdeditors.mdformatters.mdindex.mdselection.mdutilities.md

components.mddocs/

0

# Components and Customization

1

2

Core building blocks and advanced customization options for creating custom grid rendering and specialized functionality.

3

4

## Capabilities

5

6

### Core Components

7

8

Low-level components that make up the grid structure, available for advanced customization scenarios.

9

10

```javascript { .api }

11

/** Core grid row component */

12

const Row: React.ComponentType<RowProps>;

13

14

/** Individual cell component */

15

const Cell: React.ComponentType<CellProps>;

16

17

/** Header cell component */

18

const HeaderCell: React.ComponentType<HeaderCellProps>;

19

20

/** Empty child row placeholder */

21

const EmptyChildRow: React.ComponentType<EmptyChildRowProps>;

22

```

23

24

### Row Component

25

26

Individual row component that renders a collection of cells.

27

28

```javascript { .api }

29

interface RowProps {

30

/** Row index in the dataset */

31

idx: number;

32

/** Starting column index for visible columns */

33

visibleStart: number;

34

/** Ending column index for visible columns */

35

visibleEnd: number;

36

/** Row data object */

37

row: any;

38

/** Row height in pixels */

39

height: number;

40

/** Array of column definitions */

41

columns: Column[];

42

/** Whether the row is selected */

43

isSelected?: boolean;

44

/** Whether the row is being scrolled */

45

isScrolling?: boolean;

46

/** CSS classes to apply to the row */

47

extraClasses?: string;

48

/** Function to get cell actions */

49

getCellActions?: (column: Column, row: any) => CellAction[];

50

/** Cell selection range */

51

cellSelection?: SelectionRange;

52

/** Event handlers for row interactions */

53

onRowClick?: (rowIdx: number, row: any) => void;

54

onRowDoubleClick?: (rowIdx: number, row: any) => void;

55

onCellClick?: (position: Position) => void;

56

onCellDoubleClick?: (position: Position) => void;

57

onCellContextMenu?: (position: Position) => void;

58

onDragEnter?: (overRowIdx: number) => void;

59

}

60

61

/**

62

* Row component for rendering individual grid rows

63

* Handles cell rendering, selection, and user interactions

64

*/

65

const Row: React.ComponentType<RowProps>;

66

```

67

68

### Cell Component

69

70

Individual cell component that handles content rendering, editing, and interactions.

71

72

```javascript { .api }

73

interface CellProps {

74

/** Column definition */

75

column: Column;

76

/** Cell value */

77

value: any;

78

/** Complete row data */

79

row: any;

80

/** Row index */

81

rowIdx: number;

82

/** Column index */

83

idx: number;

84

/** Whether the cell is selected */

85

isSelected?: boolean;

86

/** Whether the cell is being edited */

87

isEditing?: boolean;

88

/** Whether the cell can be copied */

89

isCopied?: boolean;

90

/** Cell height in pixels */

91

height: number;

92

/** Event handlers */

93

onCellClick?: (position: Position) => void;

94

onCellDoubleClick?: (position: Position) => void;

95

onCellContextMenu?: (position: Position) => void;

96

onCellExpand?: (args: CellExpandArgs) => void;

97

onCommit?: (args: CommitArgs) => void;

98

onCommitCancel?: () => void;

99

}

100

101

/**

102

* Cell component for rendering individual grid cells

103

* Handles content display, editing, and cell-specific interactions

104

*/

105

const Cell: React.ComponentType<CellProps>;

106

```

107

108

### HeaderCell Component

109

110

Header cell component for column headers with sorting, filtering, and resizing capabilities.

111

112

```javascript { .api }

113

interface HeaderCellProps {

114

/** Column definition */

115

column: Column;

116

/** Row type (header, filter, etc.) */

117

rowType: string;

118

/** Cell height in pixels */

119

height: number;

120

/** Event handlers */

121

onSort?: (columnKey: string, direction: SortDirection) => void;

122

onResize?: (column: Column, width: number) => void;

123

onHeaderDrop?: () => void;

124

onFilterChange?: (filter: Filter) => void;

125

/** Current sort configuration */

126

sortColumn?: string;

127

sortDirection?: SortDirection;

128

/** Whether the column can be dragged */

129

draggableHeaderCell?: React.ComponentType<any>;

130

}

131

132

/**

133

* Header cell component for column headers

134

* Supports sorting, filtering, resizing, and custom header rendering

135

*/

136

const HeaderCell: React.ComponentType<HeaderCellProps>;

137

```

138

139

### EmptyChildRow Component

140

141

Placeholder component for empty child rows in hierarchical data structures.

142

143

```javascript { .api }

144

interface EmptyChildRowProps {

145

/** Row height in pixels */

146

height: number;

147

/** Column definitions */

148

columns: Column[];

149

/** Additional CSS classes */

150

extraClasses?: string;

151

}

152

153

/**

154

* Empty child row component for hierarchical data

155

* Renders placeholder rows for expanded parent rows with no children

156

*/

157

const EmptyChildRow: React.ComponentType<EmptyChildRowProps>;

158

```

159

160

### Custom Component Integration

161

162

Using core components for advanced customization scenarios.

163

164

**Custom Row Renderer Example:**

165

166

```javascript

167

import React from 'react';

168

import ReactDataGrid, { Row } from 'react-data-grid';

169

170

const CustomRow = (props) => {

171

const { row, idx } = props;

172

173

// Add custom styling based on row data

174

const customStyle = {

175

backgroundColor: row.priority === 'high' ? '#fff3cd' : undefined,

176

fontWeight: row.isImportant ? 'bold' : 'normal'

177

};

178

179

return (

180

<div style={customStyle}>

181

<Row {...props} />

182

</div>

183

);

184

};

185

186

// Usage with custom row renderer

187

const GridWithCustomRows = () => {

188

return (

189

<ReactDataGrid

190

columns={columns}

191

rowGetter={i => rows[i]}

192

rowsCount={rows.length}

193

minHeight={400}

194

rowGroupRenderer={CustomRow}

195

/>

196

);

197

};

198

```

199

200

**Custom Cell Actions Example:**

201

202

```javascript

203

import ReactDataGrid from 'react-data-grid';

204

205

const getCellActions = (column, row) => {

206

if (column.key === 'actions') {

207

return [

208

{

209

icon: 'edit',

210

text: 'Edit',

211

callback: () => console.log('Edit:', row)

212

},

213

{

214

icon: 'delete',

215

text: 'Delete',

216

callback: () => console.log('Delete:', row)

217

}

218

];

219

}

220

return [];

221

};

222

223

const GridWithActions = () => {

224

return (

225

<ReactDataGrid

226

columns={columns}

227

rowGetter={i => rows[i]}

228

rowsCount={rows.length}

229

minHeight={400}

230

getCellActions={getCellActions}

231

/>

232

);

233

};

234

```

235

236

### Component Types and Interfaces

237

238

Supporting types and interfaces for component customization.

239

240

```javascript { .api }

241

interface Position {

242

/** Column index */

243

idx: number;

244

/** Row index */

245

rowIdx: number;

246

}

247

248

interface SelectionRange {

249

/** Top-left position */

250

topLeft: Position;

251

/** Bottom-right position */

252

bottomRight: Position;

253

}

254

255

interface CellAction {

256

/** Action icon identifier */

257

icon: string;

258

/** Display text for the action */

259

text: string;

260

/** Callback function when action is triggered */

261

callback: () => void;

262

/** Whether the action is disabled */

263

disabled?: boolean;

264

}

265

266

interface CellExpandArgs {

267

/** Row index */

268

rowIdx: number;

269

/** Column index */

270

idx: number;

271

/** Row data */

272

rowData: any;

273

/** Expand arguments */

274

expandArgs: any;

275

}

276

277

interface CommitArgs {

278

/** Cell position */

279

position: Position;

280

/** Updated value */

281

updated: any;

282

/** Update action type */

283

action: string;

284

}

285

```

286

287

### Advanced Customization

288

289

Complex customization scenarios using core components and custom renderers.

290

291

**Custom Header with Actions:**

292

293

```javascript

294

import React from 'react';

295

296

const CustomHeaderCell = ({ column, onSort, sortColumn, sortDirection }) => {

297

const handleSort = () => {

298

const newDirection =

299

sortColumn === column.key && sortDirection === 'ASC' ? 'DESC' : 'ASC';

300

onSort(column.key, newDirection);

301

};

302

303

const getSortIcon = () => {

304

if (sortColumn !== column.key) return '↕️';

305

return sortDirection === 'ASC' ? '↑' : '↓';

306

};

307

308

return (

309

<div style={{

310

display: 'flex',

311

justifyContent: 'space-between',

312

alignItems: 'center',

313

padding: '8px'

314

}}>

315

<span>{column.name}</span>

316

<div style={{ display: 'flex', gap: '4px' }}>

317

{column.sortable && (

318

<button

319

onClick={handleSort}

320

style={{ border: 'none', background: 'none', cursor: 'pointer' }}

321

>

322

{getSortIcon()}

323

</button>

324

)}

325

<button

326

onClick={() => console.log('Filter', column.key)}

327

style={{ border: 'none', background: 'none', cursor: 'pointer' }}

328

>

329

πŸ”

330

</button>

331

</div>

332

</div>

333

);

334

};

335

336

// Usage in column definitions

337

const customColumns = [

338

{

339

key: 'id',

340

name: 'ID',

341

headerRenderer: <CustomHeaderCell />

342

},

343

{

344

key: 'name',

345

name: 'Name',

346

sortable: true,

347

headerRenderer: <CustomHeaderCell />

348

}

349

];

350

```

351

352

**Custom Cell with Rich Content:**

353

354

```javascript

355

const RichCell = ({ value, row, column }) => {

356

if (column.key === 'profile') {

357

return (

358

<div style={{

359

display: 'flex',

360

alignItems: 'center',

361

gap: '8px',

362

padding: '4px'

363

}}>

364

<img

365

src={row.avatar}

366

alt={row.name}

367

style={{

368

width: '32px',

369

height: '32px',

370

borderRadius: '50%'

371

}}

372

/>

373

<div>

374

<div style={{ fontWeight: 'bold' }}>{row.name}</div>

375

<div style={{ fontSize: '12px', color: '#666' }}>{row.email}</div>

376

</div>

377

</div>

378

);

379

}

380

381

return <div>{value}</div>;

382

};

383

384

const richColumns = [

385

{ key: 'id', name: 'ID' },

386

{

387

key: 'profile',

388

name: 'Profile',

389

formatter: <RichCell />

390

},

391

{ key: 'status', name: 'Status' }

392

];

393

```

394

395

**Custom Toolbar Integration:**

396

397

```javascript

398

const CustomToolbar = ({ onAddRow, onDeleteRows, selectedCount }) => {

399

return (

400

<div style={{

401

padding: '8px',

402

backgroundColor: '#f8f9fa',

403

borderBottom: '1px solid #dee2e6',

404

display: 'flex',

405

gap: '8px',

406

alignItems: 'center'

407

}}>

408

<button onClick={onAddRow}>Add Row</button>

409

<button

410

onClick={onDeleteRows}

411

disabled={selectedCount === 0}

412

>

413

Delete Selected ({selectedCount})

414

</button>

415

<div style={{ marginLeft: 'auto' }}>

416

Total: {rows.length} rows

417

</div>

418

</div>

419

);

420

};

421

422

const GridWithToolbar = () => {

423

const [selectedRows, setSelectedRows] = useState([]);

424

425

return (

426

<ReactDataGrid

427

columns={columns}

428

rowGetter={i => rows[i]}

429

rowsCount={rows.length}

430

minHeight={400}

431

toolbar={

432

<CustomToolbar

433

onAddRow={handleAddRow}

434

onDeleteRows={handleDeleteRows}

435

selectedCount={selectedRows.length}

436

/>

437

}

438

rowSelection={{

439

showCheckbox: true,

440

onRowsSelected: setSelectedRows,

441

selectBy: { indexes: selectedRows }

442

}}

443

/>

444

);

445

};

446

```

447

448

### Performance Optimization

449

450

Tips for optimizing custom components for better grid performance.

451

452

```javascript

453

import React, { memo, useMemo } from 'react';

454

455

// Memoized custom formatter

456

const OptimizedFormatter = memo(({ value, row, column }) => {

457

const processedValue = useMemo(() => {

458

return expensiveProcessing(value);

459

}, [value]);

460

461

return <div>{processedValue}</div>;

462

});

463

464

// Memoized row component

465

const OptimizedRow = memo((props) => {

466

return <Row {...props} />;

467

}, (prevProps, nextProps) => {

468

// Custom comparison logic

469

return (

470

prevProps.row === nextProps.row &&

471

prevProps.isSelected === nextProps.isSelected &&

472

prevProps.visibleStart === nextProps.visibleStart &&

473

prevProps.visibleEnd === nextProps.visibleEnd

474

);

475

});

476

```