Table Measurement Hook
TableMeasurement
is a custom hook of TableV2 to customize the Initial Column Widths by measuring the text content of each cell and return the array of new column widths.
By adding initialMinWidth
, initialMaxWidth
or isAutoWidth
to the columns
option, the hook will recalculate the minWidth
, width
, maxWidth
and isResizable
of the column, and overwriting the default behavior of these options.
Example
Following example is the usage of TableMeasurement
in a large table.
Table is rendering ...
Header 0
Footer_0
Header 1
Footer_1
Header 2
Footer_2
Header Long 3
Footer_3
Header 4
Footer long 4
Header 5
Footer_5
Header 6
Footer_6
Header 7
Footer_7
Header 8
Footer_8
Header 9
Footer_9
Header 10
Footer_10
Header 11
Footer_11
Header 12
Footer_12
Header 13
Footer_13
Header 14
Footer_14
Header 15
Footer_15
Header 16
Footer_16
Header 17
Footer_17
Header 18
Footer_18
Header 19
Footer_19
Header 20
Footer_20
Header 21
Footer_21
Header 22
Footer_22
Header 23
Footer_23
Header 24
Footer_24
Header 25
Footer_25
Header 26
Footer_26
Header 27
Footer_27
Header 28
Footer_28
Header 29
Footer_29
Header 30
Footer_30
Header 31
Footer_31
Header 32
Footer_32
Header 33
Footer_33
Header 34
Footer_34
Header 35
Footer_35
Header 36
Footer_36
Header 37
Footer_37
Header 38
Footer_38
Header 39
Footer_39
Header 40
Footer_40
Header 41
Footer_41
Header 42
Footer_42
Header 43
Footer_43
Header 44
Footer_44
Header 45
Footer_45
Header 46
Footer_46
Header 47
Footer_47
Header 48
Footer_48
Header 49
Footer_49
Header 50
Footer_50
Header 51
Footer_51
Header 52
Footer_52
Header 53
Footer_53
Header 54
Footer_54
Header 55
Footer_55
Header 56
Footer_56
Header 57
Footer_57
Header 58
Footer_58
Header 59
Footer_59
Header 60
Footer_60
Header 61
Footer_61
Header 62
Footer_62
Header 63
Footer_63
Header 64
Footer_64
Header 65
Footer_65
Header 66
Footer_66
Header 67
Footer_67
Header 68
Footer_68
Header 69
Footer_69
Header 70
Footer_70
Header 71
Footer_71
Header 72
Footer_72
Header 73
Footer_73
Header 74
Footer_74
Header 75
Footer_75
Header 76
Footer_76
Header 77
Footer_77
Header 78
Footer_78
Header 79
Footer_79
Header 80
Footer_80
Header 81
Footer_81
Header 82
Footer_82
Header 83
Footer_83
Header 84
Footer_84
Header 85
Footer_85
Header 86
Footer_86
Header 87
Footer_87
Header 88
Footer_88
Header 89
Footer_89
Header 90
Footer_90
Header 91
Footer_91
Header 92
Footer_92
Header 93
Footer_93
Header 94
Footer_94
Header 95
Footer_95
Header 96
Footer_96
Header 97
Footer_97
Header 98
Footer_98
Header 99
Footer_99
Header 201
Footer_201
Header 202
Footer_202
Header 203
Footer_203
Header 204
Footer_204
Header 205
Footer_205
Header 206
Footer_206
Header 207
Footer_207
Header 208
Footer_208
Header 209
Footer_209
Header 210
Footer_210
Header 211
Footer_211
Header 212
Footer_212
Header 213
Footer_213
Header 214
Footer_214
Header 215
Footer_215
Header 216
Footer_216
Header 217
Footer_217
Header 218
Footer_218
Header 219
Footer_219
Header 220
Footer_220
Header 221
Footer_221
Header 222
Footer_222
Header 223
Footer_223
Header 224
Footer_224
Header 225
Footer_225
Header 226
Footer_226
Header 227
Footer_227
Header 228
Footer_228
Header 229
Footer_229
Header 230
Footer_230
Header 231
Footer_231
Header 232
Footer_232
Header 233
Footer_233
Header 234
Footer_234
Header 235
Footer_235
Header 236
Footer_236
Header 237
Footer_237
Header 238
Footer_238
Header 239
Footer_239
Header 240
Footer_240
Header 241
Footer_241
Header 242
Footer_242
Header 243
Footer_243
Header 244
Footer_244
Header 245
Footer_245
Header 246
Footer_246
Header 247
Footer_247
Header 248
Footer_248
Header 249
Footer_249
Header 250
Footer_250
Header 251
Footer_251
Header 252
Footer_252
Header 253
Footer_253
Header 254
Footer_254
Header 255
Footer_255
Header 256
Footer_256
Header 257
Footer_257
Header 258
Footer_258
Header 259
Footer_259
Header 260
Footer_260
Header 261
Footer_261
Header 262
Footer_262
Header 263
Footer_263
Header 264
Footer_264
Header 265
Footer_265
Header 266
Footer_266
Header 267
Footer_267
Header 268
Footer_268
Header 269
Footer_269
Header 270
Footer_270
Header 271
Footer_271
Header 272
Footer_272
Header 273
Footer_273
Header 274
Footer_274
Header 275
Footer_275
Header 276
Footer_276
Header 277
Footer_277
Header 278
Footer_278
Header 279
Footer_279
Header 280
Footer_280
Header 281
Footer_281
Header 282
Footer_282
Header 283
Footer_283
Header 284
Footer_284
Header 285
Footer_285
Header 286
Footer_286
Header 287
Footer_287
Header 288
Footer_288
Header 289
Footer_289
Header 290
Footer_290
Header 291
Footer_291
Header 292
Footer_292
Header 293
Footer_293
Header 294
Footer_294
Header 295
Footer_295
Header 296
Footer_296
Header 297
Footer_297
Header 298
Footer_298
Header 299
Footer_299
import {
TableV2,
TableColumnTypes,
Button,
Badge,
TableMeasurement,
TableMeasurementType,
CellSize
} from '@adjust/components';
const LargeTable: FC = () => {
const rowSize: CellSize = 'small';
const initialColumns: TableColumnTypes[] = Array.from(
{ length: 300 },
(_, index) => {
return {
Header: () =>
index === 3 ? `Header Long ${index}` : `Header ${index}`,
accessor: `column_${index}`,
sticky: index < 2 ? 'left' : undefined,
isResizable: true,
isAutoWidth: index < 100 ? true : index > 200 ? true : false,
Cell: ({ value }: any) =>
index === 0 ? (
<Badge label={value} size={rowSize} />
) : index === 1 ? (
<Text type="link" as={<Link to="/test">{value}</Link>}></Text>
) : (
value
),
Footer: () => (index === 4 ? `Footer long ${index}` : `Footer_${index}`)
};
}
);
const initialData = Array.from({ length: 4000 }, (_, i) => {
const obj = {} as Record<string, unknown>;
Array.from({ length: 300 }, (_, index) => {
if (index === 3 || index === 4) {
obj[`column_${index}`] = `data_${i}_${index}`;
} else {
else if (i < 1000)
obj[`column_${index}`] = `data_${i}_${index} test test`;
else obj[`column_${index}`] = `data_${i}_${index} long long test test`;
}
});
return obj;
});
const [columns, setColumns] = useState(initialColumns);
const [data, setData] = useState(initialData);
const onAddColumn = () => {
setColumns([
...columns,
...Array.from({ length: 10 }, (_, index) => {
return {
Header: `Header ${columns.length + index}`,
accessor: () => `New column ${columns.length + index}`,
id: `column_${columns.length + index}`,
isResizable: true,
isAutoWidth: true,
Footer: () => `Footer_${columns.length + index}`
};
})
]);
};
const onAddData = () => {
setData([
...data,
...Array.from({ length: 100 }, (_, i) => {
const obj = {} as Record<string, unknown>;
Array.from({ length: columns.length }, (_, index) => {
obj[`column_${index}`] = `New row data ${data.length + i}_${index} `;
});
return obj;
})
]);
};
const visualProperties = {
areColumnsBordered: true
};
return (
<TableMeasurement columns={columns} data={data} size={rowSize}>
{({ isMeasuring, measuredColumns }: TableMeasurementType) => {
// eslint-disable-next-line no-console
console.log('measuredColumns', isMeasuring, measuredColumns);
return (
<>
<Button label="Add 10 Columns" size="small" onClick={onAddColumn} />
<Button label="Add 100 Rows" size="small" onClick={onAddData} />
{isMeasuring && <div>Table is rendering ...</div>}
{!isMeasuring && (
<TableV2
data={data}
columns={measuredColumns}
height={700}
rowSize={rowSize}
visualProperties={visualProperties}
/>
)}
</>
);
}}
</TableMeasurement>
);
};
Usage
<TableMeasurement columns={columns} data={data}>
{({ isMeasuring, measuredColumns }) =>
... //children: JSX.Element | ReactNode
}
</TableMeasurement>
warning
This hook only supports for the body cells which render their value (text content) from data
, not support for custom cells without data
value. Please be careful if body cells are using Custom Cell Renderer
❌ Incorrect: Cell() does not have `value` from `data`.
const columns = [
{
Header: () => 'Name',
accessor: 'name',
isAutoWidth: true,
Cell: ({ row: { original, index } }) => return <Badge>{`row ${index}`}</Badge>;
Footer: () => 'Total',
}
]
✅ Correct: Cell() has `value` from `data`.
const columns = [
{
Header: () => 'Name',
accessor: 'name',
isAutoWidth: true,
Cell: ({ value }) => return <Badge>{value}</Badge>;
Footer: () => 'Total',
}
]
Return states
The hook returns TableMeasurementType
as following:
State | Type | Desc |
---|---|---|
measuredColumns | TableColumnTypes[] | The array of columns which is passed initially and including more: {id, width, minWidth, maxWidth, isResizable} |
isMeasuring | boolean | true if the hook is measuring the column widths and hasn't returned the result |
Props
Name | Type | Default |
---|---|---|
data * |
| — |
columns * |
| — |
rowSize |
| "medium" |
isHeaderless |
| — |
isFooterless |
| — |
data-{foo} Data attributes can be used by testing libraries to retrieve components or assert their existence |
| — |
* - the prop is required. |