baseui 0.0.0-next-a3efedf → 0.0.0-next-cefa45f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data-table/data-table.js +53 -50
- package/data-table/data-table.js.flow +18 -13
- package/data-table/measure-column-widths.js +83 -121
- package/data-table/measure-column-widths.js.flow +87 -109
- package/es/data-table/data-table.js +18 -16
- package/es/data-table/measure-column-widths.js +75 -86
- package/es/utils/lcg.js +14 -0
- package/esm/data-table/data-table.js +53 -50
- package/esm/data-table/measure-column-widths.js +83 -121
- package/esm/utils/lcg.js +16 -0
- package/package.json +1 -1
- package/utils/lcg.js +24 -0
- package/utils/lcg.js.flow +21 -0
|
@@ -12,46 +12,69 @@ import {useStyletron} from '../styles/index.js';
|
|
|
12
12
|
|
|
13
13
|
import HeaderCell from './header-cell.js';
|
|
14
14
|
import type {ColumnT, RowT} from './types.js';
|
|
15
|
+
import {useRef} from 'react';
|
|
15
16
|
|
|
16
|
-
//
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
// Measures the column header + sampled data
|
|
18
|
+
function MeasureColumn({
|
|
19
|
+
sampleIndexes,
|
|
20
|
+
column,
|
|
21
|
+
columnIndex,
|
|
22
|
+
rows,
|
|
23
|
+
isSelectable,
|
|
24
|
+
onLayout,
|
|
25
|
+
}) {
|
|
26
|
+
const [css] = useStyletron();
|
|
20
27
|
|
|
21
|
-
const ref =
|
|
22
|
-
setNode(node);
|
|
23
|
-
}, []);
|
|
28
|
+
const ref = useRef();
|
|
24
29
|
|
|
25
30
|
React.useEffect(() => {
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
window.requestAnimationFrame(() => {
|
|
29
|
-
setDimensions(node.getBoundingClientRect());
|
|
30
|
-
});
|
|
31
|
-
}
|
|
31
|
+
if (ref.current) {
|
|
32
|
+
onLayout(columnIndex, ref.current.getBoundingClientRect());
|
|
32
33
|
}
|
|
33
|
-
}, [
|
|
34
|
-
|
|
35
|
-
return [ref, dimensions];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
type ElementMeasurerPropsT = {
|
|
39
|
-
onDimensionsChange: (dimensions: {width: number}) => void,
|
|
40
|
-
// eslint-disable-next-line flowtype/no-weak-types
|
|
41
|
-
item: React.Element<any>,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
function ElementMeasurer(props: ElementMeasurerPropsT) {
|
|
45
|
-
const {onDimensionsChange} = props;
|
|
46
|
-
const [ref, dimensions] = useDimensions();
|
|
47
|
-
|
|
48
|
-
React.useEffect(() => {
|
|
49
|
-
onDimensionsChange(dimensions);
|
|
50
|
-
}, [dimensions, onDimensionsChange]);
|
|
34
|
+
}, []);
|
|
51
35
|
|
|
52
|
-
return
|
|
36
|
+
return (
|
|
37
|
+
<div
|
|
38
|
+
ref={ref}
|
|
39
|
+
className={css({
|
|
40
|
+
display: 'flex',
|
|
41
|
+
flexDirection: 'column',
|
|
42
|
+
width: 'fit-content',
|
|
43
|
+
})}
|
|
44
|
+
>
|
|
45
|
+
<HeaderCell
|
|
46
|
+
index={columnIndex}
|
|
47
|
+
isHovered
|
|
48
|
+
isMeasured
|
|
49
|
+
isSelectedAll={false}
|
|
50
|
+
isSelectedIndeterminate={false}
|
|
51
|
+
onMouseEnter={() => {}}
|
|
52
|
+
onMouseLeave={() => {}}
|
|
53
|
+
onSelectAll={() => {}}
|
|
54
|
+
onSelectNone={() => {}}
|
|
55
|
+
onSort={i => {}}
|
|
56
|
+
sortable={column.sortable}
|
|
57
|
+
sortDirection={null}
|
|
58
|
+
title={column.title}
|
|
59
|
+
isSelectable={isSelectable}
|
|
60
|
+
/>
|
|
61
|
+
{sampleIndexes.map((rowIndex, i) => {
|
|
62
|
+
const Cell = column.renderCell;
|
|
63
|
+
return (
|
|
64
|
+
<Cell
|
|
65
|
+
key={`measure-${i}`}
|
|
66
|
+
value={column.mapDataToValue(rows[rowIndex].data)}
|
|
67
|
+
isSelectable={isSelectable}
|
|
68
|
+
isMeasured
|
|
69
|
+
sortable={column.sortable}
|
|
70
|
+
x={0}
|
|
71
|
+
y={rowIndex}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
})}
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
53
77
|
}
|
|
54
|
-
|
|
55
78
|
type MeasureColumnWidthsPropsT = {
|
|
56
79
|
columns: ColumnT<>[],
|
|
57
80
|
// if selectable, measure the first column with checkbox included
|
|
@@ -61,7 +84,6 @@ type MeasureColumnWidthsPropsT = {
|
|
|
61
84
|
widths: number[],
|
|
62
85
|
};
|
|
63
86
|
|
|
64
|
-
// sample size could likely be generated based on row count, to have higher confidence
|
|
65
87
|
const MAX_SAMPLE_SIZE = 50;
|
|
66
88
|
|
|
67
89
|
function generateSampleIndices(inputMin, inputMax, maxSamples) {
|
|
@@ -96,51 +118,41 @@ export default function MeasureColumnWidths({
|
|
|
96
118
|
}: MeasureColumnWidthsPropsT) {
|
|
97
119
|
const [css] = useStyletron();
|
|
98
120
|
|
|
99
|
-
const
|
|
100
|
-
|
|
121
|
+
const widthMap = React.useMemo(() => {
|
|
122
|
+
return new Map();
|
|
123
|
+
}, []);
|
|
101
124
|
|
|
102
125
|
const sampleSize =
|
|
103
126
|
rows.length < MAX_SAMPLE_SIZE ? rows.length : MAX_SAMPLE_SIZE;
|
|
104
127
|
const finishedMeasurementCount = (sampleSize + 1) * columns.length;
|
|
105
128
|
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
dimensionsCache.current = widths;
|
|
109
|
-
|
|
110
|
-
const indices = generateSampleIndices(0, rows.length - 1, sampleSize);
|
|
111
|
-
return columns.map(() => indices);
|
|
129
|
+
const sampleIndexes = React.useMemo<number[]>(() => {
|
|
130
|
+
return generateSampleIndices(0, rows.length - 1, sampleSize);
|
|
112
131
|
}, [columns, rows, widths, sampleSize]);
|
|
113
132
|
|
|
114
133
|
const handleDimensionsChange = React.useCallback(
|
|
115
|
-
(columnIndex,
|
|
116
|
-
if (dimensions.width === undefined) return;
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
columns[columnIndex] === undefined ||
|
|
120
|
-
dimensionsCache.current[columnIndex] === undefined
|
|
121
|
-
) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
measurementCount.current += 1;
|
|
126
|
-
|
|
134
|
+
(columnIndex, dimensions) => {
|
|
127
135
|
const nextWidth = Math.min(
|
|
128
136
|
Math.max(
|
|
129
137
|
columns[columnIndex].minWidth || 0,
|
|
130
|
-
|
|
138
|
+
widthMap.get(columnIndex) || 0,
|
|
131
139
|
dimensions.width + 1,
|
|
132
140
|
),
|
|
133
141
|
columns[columnIndex].maxWidth || Infinity,
|
|
134
142
|
);
|
|
135
143
|
|
|
136
|
-
if (nextWidth !==
|
|
137
|
-
|
|
138
|
-
nextWidths[columnIndex] = nextWidth;
|
|
139
|
-
dimensionsCache.current = nextWidths;
|
|
144
|
+
if (nextWidth !== widthMap.get(columnIndex)) {
|
|
145
|
+
widthMap.set(columnIndex, nextWidth);
|
|
140
146
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
147
|
+
if (
|
|
148
|
+
// Refresh at 100% of done
|
|
149
|
+
widthMap.size === columns.length ||
|
|
150
|
+
// ...50%
|
|
151
|
+
widthMap.size === Math.floor(columns.length / 2) ||
|
|
152
|
+
// ...25%
|
|
153
|
+
widthMap.size === Math.floor(columns.length / 4)
|
|
154
|
+
) {
|
|
155
|
+
onWidthsChange(Array.from(widthMap.values()));
|
|
144
156
|
}
|
|
145
157
|
},
|
|
146
158
|
[columns, finishedMeasurementCount, onWidthsChange],
|
|
@@ -152,61 +164,27 @@ export default function MeasureColumnWidths({
|
|
|
152
164
|
height: 0,
|
|
153
165
|
});
|
|
154
166
|
|
|
155
|
-
|
|
167
|
+
// Remove the measurement nodes after we are done updating our column width
|
|
168
|
+
if (widthMap.size === columns.length) {
|
|
156
169
|
return null;
|
|
157
170
|
}
|
|
158
171
|
|
|
159
172
|
return (
|
|
160
173
|
// eslint-disable-next-line jsx-a11y/role-supports-aria-props
|
|
161
174
|
<div className={hiddenStyle} aria-hidden role="none">
|
|
162
|
-
{
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
value={columns[columnIndex].mapDataToValue(rows[rowIndex].data)}
|
|
173
|
-
isMeasured
|
|
174
|
-
onSelect={
|
|
175
|
-
isSelectable && columnIndex === 0 ? () => {} : undefined
|
|
176
|
-
}
|
|
177
|
-
x={columnIndex}
|
|
178
|
-
y={rowIndex}
|
|
179
|
-
/>
|
|
180
|
-
}
|
|
175
|
+
{columns.map((column, i) => {
|
|
176
|
+
return (
|
|
177
|
+
<MeasureColumn
|
|
178
|
+
key={column.title + i}
|
|
179
|
+
column={column}
|
|
180
|
+
rows={rows}
|
|
181
|
+
isSelectable={isSelectable}
|
|
182
|
+
onLayout={handleDimensionsChange}
|
|
183
|
+
columnIndex={i}
|
|
184
|
+
sampleIndexes={sampleIndexes}
|
|
181
185
|
/>
|
|
182
|
-
)
|
|
186
|
+
);
|
|
183
187
|
})}
|
|
184
|
-
{columns.map((column, columnIndex) => (
|
|
185
|
-
<ElementMeasurer
|
|
186
|
-
key={`measure-column-${columnIndex}`}
|
|
187
|
-
onDimensionsChange={dimensions =>
|
|
188
|
-
handleDimensionsChange(columnIndex, -1, dimensions)
|
|
189
|
-
}
|
|
190
|
-
item={
|
|
191
|
-
<HeaderCell
|
|
192
|
-
index={columnIndex}
|
|
193
|
-
isHovered
|
|
194
|
-
isMeasured
|
|
195
|
-
isSelectable={isSelectable && columnIndex === 0}
|
|
196
|
-
isSelectedAll={false}
|
|
197
|
-
isSelectedIndeterminate={false}
|
|
198
|
-
onMouseEnter={() => {}}
|
|
199
|
-
onMouseLeave={() => {}}
|
|
200
|
-
onSelectAll={() => {}}
|
|
201
|
-
onSelectNone={() => {}}
|
|
202
|
-
onSort={i => {}}
|
|
203
|
-
sortable={column.sortable}
|
|
204
|
-
sortDirection={null}
|
|
205
|
-
title={column.title}
|
|
206
|
-
/>
|
|
207
|
-
}
|
|
208
|
-
/>
|
|
209
|
-
))}
|
|
210
188
|
</div>
|
|
211
189
|
);
|
|
212
190
|
}
|
|
@@ -17,6 +17,8 @@ import { LocaleContext } from '../locale/index.js'; // consider pulling this out
|
|
|
17
17
|
|
|
18
18
|
const HEADER_ROW_HEIGHT = 48;
|
|
19
19
|
|
|
20
|
+
const sum = ns => ns.reduce((s, n) => s + n, 0);
|
|
21
|
+
|
|
20
22
|
function CellPlacement({
|
|
21
23
|
columnIndex,
|
|
22
24
|
rowIndex,
|
|
@@ -255,7 +257,7 @@ function Header(props) {
|
|
|
255
257
|
}))));
|
|
256
258
|
}
|
|
257
259
|
|
|
258
|
-
function Headers(
|
|
260
|
+
function Headers() {
|
|
259
261
|
const [css, theme] = useStyletron();
|
|
260
262
|
const locale = React.useContext(LocaleContext);
|
|
261
263
|
const ctx = React.useContext(HeaderContext);
|
|
@@ -265,7 +267,7 @@ function Headers(props) {
|
|
|
265
267
|
position: 'sticky',
|
|
266
268
|
top: 0,
|
|
267
269
|
left: 0,
|
|
268
|
-
width: `${ctx.widths
|
|
270
|
+
width: `${sum(ctx.widths)}px`,
|
|
269
271
|
height: `${HEADER_ROW_HEIGHT}px`,
|
|
270
272
|
display: 'flex',
|
|
271
273
|
// this feels bad.. the absolutely positioned children elements
|
|
@@ -467,8 +469,10 @@ export function DataTable({
|
|
|
467
469
|
}
|
|
468
470
|
|
|
469
471
|
return rowHeight;
|
|
470
|
-
}, [rowHeight]);
|
|
471
|
-
|
|
472
|
+
}, [rowHeight]); // We use state for our ref, to allow hooks to update when the ref changes.
|
|
473
|
+
// eslint-disable-next-line flowtype/no-weak-types
|
|
474
|
+
|
|
475
|
+
const [gridRef, setGridRef] = React.useState(null);
|
|
472
476
|
const [measuredWidths, setMeasuredWidths] = React.useState(columns.map(() => 0));
|
|
473
477
|
const [resizeDeltas, setResizeDeltas] = React.useState(columns.map(() => 0));
|
|
474
478
|
React.useEffect(() => {
|
|
@@ -480,11 +484,11 @@ export function DataTable({
|
|
|
480
484
|
});
|
|
481
485
|
}, [columns]);
|
|
482
486
|
const resetAfterColumnIndex = React.useCallback(columnIndex => {
|
|
483
|
-
if (gridRef
|
|
487
|
+
if (gridRef) {
|
|
484
488
|
// $FlowFixMe trigger react-window to layout the elements again
|
|
485
|
-
gridRef.
|
|
489
|
+
gridRef.resetAfterColumnIndex(columnIndex, true);
|
|
486
490
|
}
|
|
487
|
-
}, [gridRef
|
|
491
|
+
}, [gridRef]);
|
|
488
492
|
const handleWidthsChange = React.useCallback(nextWidths => {
|
|
489
493
|
setMeasuredWidths(nextWidths);
|
|
490
494
|
resetAfterColumnIndex(0);
|
|
@@ -594,13 +598,10 @@ export function DataTable({
|
|
|
594
598
|
}, [sortedIndices, filteredIndices, onIncludedRowsChange, allRows]);
|
|
595
599
|
const [browserScrollbarWidth, setBrowserScrollbarWidth] = React.useState(0);
|
|
596
600
|
const normalizedWidths = React.useMemo(() => {
|
|
597
|
-
const sum = ns => ns.reduce((s, n) => s + n, 0);
|
|
598
|
-
|
|
599
601
|
const resizedWidths = measuredWidths.map((w, i) => Math.floor(w) + Math.floor(resizeDeltas[i]));
|
|
600
602
|
|
|
601
|
-
if (gridRef
|
|
602
|
-
|
|
603
|
-
const gridProps = gridRef.current.props;
|
|
603
|
+
if (gridRef) {
|
|
604
|
+
const gridProps = gridRef.props;
|
|
604
605
|
let isContentTallerThanContainer = false;
|
|
605
606
|
let visibleRowHeight = 0;
|
|
606
607
|
|
|
@@ -635,7 +636,7 @@ export function DataTable({
|
|
|
635
636
|
}
|
|
636
637
|
|
|
637
638
|
return resizedWidths;
|
|
638
|
-
}, [measuredWidths, resizeDeltas, browserScrollbarWidth, rows.length, columns]);
|
|
639
|
+
}, [gridRef, measuredWidths, resizeDeltas, browserScrollbarWidth, rows.length, columns]);
|
|
639
640
|
const isSelectable = batchActions ? !!batchActions.length : false;
|
|
640
641
|
const isSelectedAll = React.useMemo(() => {
|
|
641
642
|
if (!selectedRowIds) {
|
|
@@ -684,10 +685,10 @@ export function DataTable({
|
|
|
684
685
|
function handleRowHighlightIndexChange(nextIndex) {
|
|
685
686
|
setRowHighlightIndex(nextIndex);
|
|
686
687
|
|
|
687
|
-
if (gridRef
|
|
688
|
+
if (gridRef) {
|
|
688
689
|
if (nextIndex >= 0) {
|
|
689
690
|
// $FlowFixMe - unable to get react-window types
|
|
690
|
-
gridRef.
|
|
691
|
+
gridRef.scrollToItem({
|
|
691
692
|
rowIndex: nextIndex
|
|
692
693
|
});
|
|
693
694
|
}
|
|
@@ -776,8 +777,9 @@ export function DataTable({
|
|
|
776
777
|
}
|
|
777
778
|
}, /*#__PURE__*/React.createElement(VariableSizeGrid // eslint-disable-next-line flowtype/no-weak-types
|
|
778
779
|
, {
|
|
779
|
-
ref:
|
|
780
|
+
ref: setGridRef,
|
|
780
781
|
overscanRowCount: 10,
|
|
782
|
+
overscanColumnCount: 5,
|
|
781
783
|
innerElementType: InnerTableElement,
|
|
782
784
|
columnCount: columns.length,
|
|
783
785
|
columnWidth: columnIndex => normalizedWidths[columnIndex],
|
|
@@ -7,40 +7,59 @@ LICENSE file in the root directory of this source tree.
|
|
|
7
7
|
import * as React from 'react';
|
|
8
8
|
import { useStyletron } from '../styles/index.js';
|
|
9
9
|
import HeaderCell from './header-cell.js';
|
|
10
|
+
import { useRef } from 'react'; // Measures the column header + sampled data
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
function MeasureColumn({
|
|
13
|
+
sampleIndexes,
|
|
14
|
+
column,
|
|
15
|
+
columnIndex,
|
|
16
|
+
rows,
|
|
17
|
+
isSelectable,
|
|
18
|
+
onLayout
|
|
19
|
+
}) {
|
|
20
|
+
const [css] = useStyletron();
|
|
21
|
+
const ref = useRef();
|
|
18
22
|
React.useEffect(() => {
|
|
19
|
-
if (
|
|
20
|
-
|
|
21
|
-
window.requestAnimationFrame(() => {
|
|
22
|
-
setDimensions(node.getBoundingClientRect());
|
|
23
|
-
});
|
|
24
|
-
}
|
|
23
|
+
if (ref.current) {
|
|
24
|
+
onLayout(columnIndex, ref.current.getBoundingClientRect());
|
|
25
25
|
}
|
|
26
|
-
}, [
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
26
|
+
}, []);
|
|
27
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
28
|
+
ref: ref,
|
|
29
|
+
className: css({
|
|
30
|
+
display: 'flex',
|
|
31
|
+
flexDirection: 'column',
|
|
32
|
+
width: 'fit-content'
|
|
33
|
+
})
|
|
34
|
+
}, /*#__PURE__*/React.createElement(HeaderCell, {
|
|
35
|
+
index: columnIndex,
|
|
36
|
+
isHovered: true,
|
|
37
|
+
isMeasured: true,
|
|
38
|
+
isSelectedAll: false,
|
|
39
|
+
isSelectedIndeterminate: false,
|
|
40
|
+
onMouseEnter: () => {},
|
|
41
|
+
onMouseLeave: () => {},
|
|
42
|
+
onSelectAll: () => {},
|
|
43
|
+
onSelectNone: () => {},
|
|
44
|
+
onSort: i => {},
|
|
45
|
+
sortable: column.sortable,
|
|
46
|
+
sortDirection: null,
|
|
47
|
+
title: column.title,
|
|
48
|
+
isSelectable: isSelectable
|
|
49
|
+
}), sampleIndexes.map((rowIndex, i) => {
|
|
50
|
+
const Cell = column.renderCell;
|
|
51
|
+
return /*#__PURE__*/React.createElement(Cell, {
|
|
52
|
+
key: `measure-${i}`,
|
|
53
|
+
value: column.mapDataToValue(rows[rowIndex].data),
|
|
54
|
+
isSelectable: isSelectable,
|
|
55
|
+
isMeasured: true,
|
|
56
|
+
sortable: column.sortable,
|
|
57
|
+
x: 0,
|
|
58
|
+
y: rowIndex
|
|
59
|
+
});
|
|
60
|
+
}));
|
|
41
61
|
}
|
|
42
62
|
|
|
43
|
-
// sample size could likely be generated based on row count, to have higher confidence
|
|
44
63
|
const MAX_SAMPLE_SIZE = 50;
|
|
45
64
|
|
|
46
65
|
function generateSampleIndices(inputMin, inputMax, maxSamples) {
|
|
@@ -77,43 +96,35 @@ export default function MeasureColumnWidths({
|
|
|
77
96
|
onWidthsChange
|
|
78
97
|
}) {
|
|
79
98
|
const [css] = useStyletron();
|
|
80
|
-
const
|
|
81
|
-
|
|
99
|
+
const widthMap = React.useMemo(() => {
|
|
100
|
+
return new Map();
|
|
101
|
+
}, []);
|
|
82
102
|
const sampleSize = rows.length < MAX_SAMPLE_SIZE ? rows.length : MAX_SAMPLE_SIZE;
|
|
83
103
|
const finishedMeasurementCount = (sampleSize + 1) * columns.length;
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
dimensionsCache.current = widths;
|
|
87
|
-
const indices = generateSampleIndices(0, rows.length - 1, sampleSize);
|
|
88
|
-
return columns.map(() => indices);
|
|
104
|
+
const sampleIndexes = React.useMemo(() => {
|
|
105
|
+
return generateSampleIndices(0, rows.length - 1, sampleSize);
|
|
89
106
|
}, [columns, rows, widths, sampleSize]);
|
|
90
|
-
const handleDimensionsChange = React.useCallback((columnIndex,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (columns[columnIndex] === undefined || dimensionsCache.current[columnIndex] === undefined) {
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
measurementCount.current += 1;
|
|
98
|
-
const nextWidth = Math.min(Math.max(columns[columnIndex].minWidth || 0, dimensionsCache.current[columnIndex], dimensions.width + 1), columns[columnIndex].maxWidth || Infinity);
|
|
107
|
+
const handleDimensionsChange = React.useCallback((columnIndex, dimensions) => {
|
|
108
|
+
const nextWidth = Math.min(Math.max(columns[columnIndex].minWidth || 0, widthMap.get(columnIndex) || 0, dimensions.width + 1), columns[columnIndex].maxWidth || Infinity);
|
|
99
109
|
|
|
100
|
-
if (nextWidth !==
|
|
101
|
-
|
|
102
|
-
nextWidths[columnIndex] = nextWidth;
|
|
103
|
-
dimensionsCache.current = nextWidths;
|
|
110
|
+
if (nextWidth !== widthMap.get(columnIndex)) {
|
|
111
|
+
widthMap.set(columnIndex, nextWidth);
|
|
104
112
|
}
|
|
105
113
|
|
|
106
|
-
if (
|
|
107
|
-
|
|
114
|
+
if ( // Refresh at 100% of done
|
|
115
|
+
widthMap.size === columns.length || // ...50%
|
|
116
|
+
widthMap.size === Math.floor(columns.length / 2) || // ...25%
|
|
117
|
+
widthMap.size === Math.floor(columns.length / 4)) {
|
|
118
|
+
onWidthsChange(Array.from(widthMap.values()));
|
|
108
119
|
}
|
|
109
120
|
}, [columns, finishedMeasurementCount, onWidthsChange]);
|
|
110
121
|
const hiddenStyle = css({
|
|
111
122
|
position: 'absolute',
|
|
112
123
|
overflow: 'hidden',
|
|
113
124
|
height: 0
|
|
114
|
-
});
|
|
125
|
+
}); // Remove the measurement nodes after we are done updating our column width
|
|
115
126
|
|
|
116
|
-
if (
|
|
127
|
+
if (widthMap.size === columns.length) {
|
|
117
128
|
return null;
|
|
118
129
|
}
|
|
119
130
|
|
|
@@ -124,38 +135,16 @@ export default function MeasureColumnWidths({
|
|
|
124
135
|
className: hiddenStyle,
|
|
125
136
|
"aria-hidden": true,
|
|
126
137
|
role: "none"
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
})
|
|
139
|
-
}));
|
|
140
|
-
}), columns.map((column, columnIndex) => /*#__PURE__*/React.createElement(ElementMeasurer, {
|
|
141
|
-
key: `measure-column-${columnIndex}`,
|
|
142
|
-
onDimensionsChange: dimensions => handleDimensionsChange(columnIndex, -1, dimensions),
|
|
143
|
-
item: /*#__PURE__*/React.createElement(HeaderCell, {
|
|
144
|
-
index: columnIndex,
|
|
145
|
-
isHovered: true,
|
|
146
|
-
isMeasured: true,
|
|
147
|
-
isSelectable: isSelectable && columnIndex === 0,
|
|
148
|
-
isSelectedAll: false,
|
|
149
|
-
isSelectedIndeterminate: false,
|
|
150
|
-
onMouseEnter: () => {},
|
|
151
|
-
onMouseLeave: () => {},
|
|
152
|
-
onSelectAll: () => {},
|
|
153
|
-
onSelectNone: () => {},
|
|
154
|
-
onSort: i => {},
|
|
155
|
-
sortable: column.sortable,
|
|
156
|
-
sortDirection: null,
|
|
157
|
-
title: column.title
|
|
158
|
-
})
|
|
159
|
-
})))
|
|
138
|
+
}, columns.map((column, i) => {
|
|
139
|
+
return /*#__PURE__*/React.createElement(MeasureColumn, {
|
|
140
|
+
key: column.title + i,
|
|
141
|
+
column: column,
|
|
142
|
+
rows: rows,
|
|
143
|
+
isSelectable: isSelectable,
|
|
144
|
+
onLayout: handleDimensionsChange,
|
|
145
|
+
columnIndex: i,
|
|
146
|
+
sampleIndexes: sampleIndexes
|
|
147
|
+
});
|
|
148
|
+
}))
|
|
160
149
|
);
|
|
161
150
|
}
|
package/es/utils/lcg.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) Uber Technologies, Inc.
|
|
3
|
+
|
|
4
|
+
This source code is licensed under the MIT license found in the
|
|
5
|
+
LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
// https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
|
|
8
|
+
const mul = 0x19660d;
|
|
9
|
+
const inc = 0x3c6ef35f;
|
|
10
|
+
const eps = 1 / 0x100000000;
|
|
11
|
+
export default function lcg(seed) {
|
|
12
|
+
let state = (0 <= seed && seed < 1 ? seed / eps : Math.abs(seed)) | 0;
|
|
13
|
+
return () => (state = mul * state + inc | 0, eps * (state >>> 0));
|
|
14
|
+
}
|