or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

built-in-types.mdcolumn-management.mdcore-table.mdfiltering.mdgrouping.mdindex.mdlayout.mdpagination.mdrow-features.mdsorting.mdutilities.md

grouping.mddocs/

0

# Data Grouping

1

2

React Table provides comprehensive data grouping capabilities through the `useGroupBy` hook. This feature allows you to group rows by column values, create hierarchical data structures, and apply aggregation functions to grouped data.

3

4

## Capabilities

5

6

### Data Grouping (useGroupBy)

7

8

Enables row grouping by column values with support for multiple grouping levels, custom aggregation functions, and expandable group headers.

9

10

```javascript { .api }

11

/**

12

* Adds row grouping capabilities to the table

13

* @param hooks - Hook registration object

14

*/

15

function useGroupBy(hooks: Hooks): void;

16

17

/**

18

* Default grouping function that groups rows by column accessor values

19

* @param rows - Array of rows to group

20

* @param columnId - Column ID to group by

21

* @returns Grouped rows structure

22

*/

23

function defaultGroupByFn(rows: Row[], columnId: string): Row[];

24

25

interface GroupByInstance {

26

/** Toggle grouping for a specific column */

27

toggleGroupBy: (columnId: string, value?: boolean) => void;

28

/** Set the groupBy configuration */

29

setGroupBy: (groupBy: string[]) => void;

30

/** Rows before grouping was applied */

31

preGroupedRows: Row[];

32

/** Flat rows before grouping */

33

preGroupedFlatRows: Row[];

34

/** Rows after grouping */

35

groupedRows: Row[];

36

/** Flat rows after grouping */

37

groupedFlatRows: Row[];

38

/** Non-grouped rows mapped by ID */

39

nonGroupedRowsById: Record<string, Row>;

40

}

41

42

interface GroupByColumnInstance {

43

/** Whether this column can be grouped */

44

canGroupBy: boolean;

45

/** Whether this column is currently grouped */

46

isGrouped: boolean;

47

/** Index of this column in the groupBy array */

48

groupedIndex: number;

49

/** Toggle grouping for this column */

50

toggleGroupBy: (value?: boolean) => void;

51

/** Get props for group by toggle UI */

52

getGroupByToggleProps: (userProps?: any) => object;

53

}

54

55

interface GroupByState {

56

/** Array of column IDs to group by, in order */

57

groupBy: string[];

58

}

59

```

60

61

**Usage Examples:**

62

63

```javascript

64

import React from 'react';

65

import { useTable, useGroupBy } from 'react-table';

66

67

function GroupedTable({ columns, data }) {

68

const {

69

getTableProps,

70

getTableBodyProps,

71

headerGroups,

72

rows,

73

prepareRow,

74

state: { groupBy },

75

setGroupBy,

76

} = useTable(

77

{

78

columns,

79

data,

80

initialState: {

81

groupBy: ['category'], // Group by category initially

82

},

83

},

84

useGroupBy // Add grouping functionality

85

);

86

87

return (

88

<div>

89

<div>

90

<label>

91

Group By:

92

<select

93

value={groupBy[0] || ''}

94

onChange={e => setGroupBy(e.target.value ? [e.target.value] : [])}

95

>

96

<option value="">No Grouping</option>

97

<option value="category">Category</option>

98

<option value="status">Status</option>

99

</select>

100

</label>

101

</div>

102

103

<table {...getTableProps()}>

104

<thead>

105

{headerGroups.map(headerGroup => (

106

<tr {...headerGroup.getHeaderGroupProps()}>

107

{headerGroup.headers.map(column => (

108

<th {...column.getHeaderProps()}>

109

{column.render('Header')}

110

{column.canGroupBy && (

111

<button

112

{...column.getGroupByToggleProps()}

113

style={{

114

marginLeft: '8px',

115

backgroundColor: column.isGrouped ? '#007bff' : '#6c757d',

116

color: 'white',

117

border: 'none',

118

padding: '2px 6px',

119

borderRadius: '3px',

120

fontSize: '12px',

121

}}

122

>

123

{column.isGrouped ? 'Ungroup' : 'Group'}

124

</button>

125

)}

126

</th>

127

))}

128

</tr>

129

))}

130

</thead>

131

<tbody {...getTableBodyProps()}>

132

{rows.map(row => {

133

prepareRow(row);

134

135

// Group header row

136

if (row.isGrouped) {

137

return (

138

<tr {...row.getRowProps()}>

139

<td

140

{...row.cells[0].getCellProps()}

141

colSpan={columns.length}

142

style={{

143

fontWeight: 'bold',

144

backgroundColor: '#f8f9fa',

145

padding: '8px',

146

}}

147

>

148

{row.groupByID}: {row.groupByVal} ({row.subRows.length} items)

149

</td>

150

</tr>

151

);

152

}

153

154

// Regular data row

155

return (

156

<tr {...row.getRowProps()}>

157

{row.cells.map(cell => (

158

<td {...cell.getCellProps()}>

159

{cell.isGrouped ? (

160

<span style={{ fontWeight: 'bold' }}>

161

{cell.render('Cell')} ({row.subRows.length})

162

</span>

163

) : cell.isAggregated ? (

164

cell.render('Aggregated')

165

) : cell.isPlaceholder ? null : (

166

cell.render('Cell')

167

)}

168

</td>

169

))}

170

</tr>

171

);

172

})}

173

</tbody>

174

</table>

175

</div>

176

);

177

}

178

```

179

180

### Multi-level Grouping

181

182

Group by multiple columns to create nested hierarchical structures:

183

184

```javascript

185

const table = useTable(

186

{

187

columns,

188

data,

189

initialState: {

190

groupBy: ['category', 'status'], // Group by category, then status

191

},

192

},

193

useGroupBy

194

);

195

```

196

197

### Custom Aggregation Functions

198

199

Define how grouped data should be aggregated for display:

200

201

```javascript

202

const columns = [

203

{

204

Header: 'Product',

205

accessor: 'product',

206

},

207

{

208

Header: 'Category',

209

accessor: 'category',

210

},

211

{

212

Header: 'Sales',

213

accessor: 'sales',

214

aggregate: 'sum', // Built-in sum aggregation

215

Aggregated: ({ value }) => `Total: ${value}`,

216

},

217

{

218

Header: 'Units',

219

accessor: 'units',

220

aggregate: (leafValues) => {

221

// Custom aggregation function

222

return leafValues.reduce((sum, val) => sum + val, 0);

223

},

224

Aggregated: ({ value }) => `${value} units`,

225

},

226

];

227

```

228

229

## Built-in Aggregation Functions

230

231

React Table provides several built-in aggregation functions:

232

233

```javascript { .api }

234

// Built-in aggregation functions

235

const aggregations = {

236

/** Sum all values */

237

sum: (leafValues: any[]) => number;

238

/** Find minimum value */

239

min: (leafValues: any[]) => number;

240

/** Find maximum value */

241

max: (leafValues: any[]) => number;

242

/** Calculate average */

243

average: (leafValues: any[]) => number;

244

/** Calculate median */

245

median: (leafValues: any[]) => number;

246

/** Get unique values as array */

247

unique: (leafValues: any[]) => any[];

248

/** Count unique values */

249

uniqueCount: (leafValues: any[]) => number;

250

/** Count all values */

251

count: (leafValues: any[]) => number;

252

/** Get min-max range as string */

253

minMax: (leafValues: any[]) => string;

254

};

255

```

256

257

## Types

258

259

```javascript { .api }

260

interface GroupByRow extends Row {

261

/** Whether this row represents a group header */

262

isGrouped: boolean;

263

/** Column ID this group is grouped by */

264

groupByID?: string;

265

/** Value this group represents */

266

groupByVal?: any;

267

/** Depth level of this group */

268

depth: number;

269

/** Leaf rows in this group */

270

leafRows?: Row[];

271

/** Sub-groups or sub-rows */

272

subRows: Row[];

273

}

274

275

interface GroupByCell extends Cell {

276

/** Whether this cell is grouped (group header cell) */

277

isGrouped: boolean;

278

/** Whether this cell shows aggregated data */

279

isAggregated: boolean;

280

/** Whether this cell is a placeholder in a grouped row */

281

isPlaceholder: boolean;

282

}

283

284

interface Column {

285

/** Aggregation function or function name */

286

aggregate?: string | ((leafValues: any[], childRows: Row[]) => any);

287

/** Component to render aggregated values */

288

Aggregated?: Renderer;

289

/** Whether this column can be grouped */

290

canGroupBy?: boolean;

291

/** Whether to disable grouping for this column */

292

disableGroupBy?: boolean;

293

}

294

```