baseui 10.9.0 → 10.9.1

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.
Files changed (39) hide show
  1. package/data-table/column-numerical.js +355 -307
  2. package/data-table/column-numerical.js.flow +287 -273
  3. package/data-table/constants.js +11 -17
  4. package/data-table/constants.js.flow +8 -11
  5. package/data-table/data-table.js +50 -53
  6. package/data-table/data-table.js.flow +13 -18
  7. package/data-table/filter-shell.js +4 -27
  8. package/data-table/filter-shell.js.flow +9 -33
  9. package/data-table/locale.js +2 -4
  10. package/data-table/locale.js.flow +2 -6
  11. package/data-table/measure-column-widths.js +121 -83
  12. package/data-table/measure-column-widths.js.flow +109 -87
  13. package/es/data-table/column-numerical.js +317 -245
  14. package/es/data-table/constants.js +8 -12
  15. package/es/data-table/data-table.js +16 -18
  16. package/es/data-table/filter-shell.js +4 -26
  17. package/es/data-table/locale.js +2 -4
  18. package/es/data-table/measure-column-widths.js +86 -75
  19. package/es/form-control/form-control.js +58 -7
  20. package/es/form-control/styled-components.js +27 -6
  21. package/es/popover/popover.js +1 -1
  22. package/esm/data-table/column-numerical.js +353 -304
  23. package/esm/data-table/constants.js +8 -12
  24. package/esm/data-table/data-table.js +50 -53
  25. package/esm/data-table/filter-shell.js +4 -26
  26. package/esm/data-table/locale.js +2 -4
  27. package/esm/data-table/measure-column-widths.js +121 -83
  28. package/esm/form-control/form-control.js +60 -9
  29. package/esm/form-control/styled-components.js +23 -3
  30. package/esm/popover/popover.js +1 -1
  31. package/form-control/form-control.js +61 -8
  32. package/form-control/form-control.js.flow +82 -10
  33. package/form-control/index.d.ts +1 -0
  34. package/form-control/styled-components.js +27 -5
  35. package/form-control/styled-components.js.flow +25 -3
  36. package/form-control/types.js.flow +20 -8
  37. package/package.json +1 -2
  38. package/popover/popover.js +1 -1
  39. package/popover/popover.js.flow +1 -1
@@ -19,6 +19,14 @@ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return
19
19
 
20
20
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
21
 
22
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
23
+
24
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
25
+
26
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
27
+
28
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
29
+
22
30
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
23
31
 
24
32
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -31,61 +39,50 @@ function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(
31
39
 
32
40
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
33
41
 
34
- // Measures the column header + sampled data
35
- function MeasureColumn(_ref) {
36
- var sampleIndexes = _ref.sampleIndexes,
37
- column = _ref.column,
38
- columnIndex = _ref.columnIndex,
39
- rows = _ref.rows,
40
- isSelectable = _ref.isSelectable,
41
- onLayout = _ref.onLayout;
42
+ // https://github.com/Swizec/useDimensions
43
+ function useDimensions() {
44
+ var _React$useState = React.useState({}),
45
+ _React$useState2 = _slicedToArray(_React$useState, 2),
46
+ dimensions = _React$useState2[0],
47
+ setDimensions = _React$useState2[1];
42
48
 
43
- var _useStyletron = (0, _index.useStyletron)(),
44
- _useStyletron2 = _slicedToArray(_useStyletron, 1),
45
- css = _useStyletron2[0];
49
+ var _React$useState3 = React.useState(null),
50
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
51
+ node = _React$useState4[0],
52
+ setNode = _React$useState4[1];
46
53
 
47
- var ref = (0, React.useRef)();
54
+ var ref = React.useCallback(function (node) {
55
+ setNode(node);
56
+ }, []);
48
57
  React.useEffect(function () {
49
- if (ref.current) {
50
- onLayout(columnIndex, ref.current.getBoundingClientRect());
58
+ if (typeof document !== 'undefined') {
59
+ if (node) {
60
+ window.requestAnimationFrame(function () {
61
+ setDimensions(node.getBoundingClientRect());
62
+ });
63
+ }
51
64
  }
52
- }, []);
53
- return /*#__PURE__*/React.createElement("div", {
54
- ref: ref,
55
- className: css({
56
- display: 'flex',
57
- flexDirection: 'column',
58
- width: 'fit-content'
59
- })
60
- }, /*#__PURE__*/React.createElement(_headerCell.default, {
61
- index: columnIndex,
62
- isHovered: true,
63
- isMeasured: true,
64
- isSelectedAll: false,
65
- isSelectedIndeterminate: false,
66
- onMouseEnter: function onMouseEnter() {},
67
- onMouseLeave: function onMouseLeave() {},
68
- onSelectAll: function onSelectAll() {},
69
- onSelectNone: function onSelectNone() {},
70
- onSort: function onSort(i) {},
71
- sortable: column.sortable,
72
- sortDirection: null,
73
- title: column.title,
74
- isSelectable: isSelectable
75
- }), sampleIndexes.map(function (rowIndex, i) {
76
- var Cell = column.renderCell;
77
- return /*#__PURE__*/React.createElement(Cell, {
78
- key: "measure-".concat(i),
79
- value: column.mapDataToValue(rows[rowIndex].data),
80
- isSelectable: isSelectable,
81
- isMeasured: true,
82
- sortable: column.sortable,
83
- x: 0,
84
- y: rowIndex
85
- });
86
- }));
65
+ }, [node]);
66
+ return [ref, dimensions];
67
+ }
68
+
69
+ function ElementMeasurer(props) {
70
+ var onDimensionsChange = props.onDimensionsChange;
71
+
72
+ var _useDimensions = useDimensions(),
73
+ _useDimensions2 = _slicedToArray(_useDimensions, 2),
74
+ ref = _useDimensions2[0],
75
+ dimensions = _useDimensions2[1];
76
+
77
+ React.useEffect(function () {
78
+ onDimensionsChange(dimensions);
79
+ }, [dimensions, onDimensionsChange]);
80
+ return /*#__PURE__*/React.cloneElement(props.item, {
81
+ ref: ref
82
+ });
87
83
  }
88
84
 
85
+ // sample size could likely be generated based on row count, to have higher confidence
89
86
  var MAX_SAMPLE_SIZE = 50;
90
87
 
91
88
  function generateSampleIndices(inputMin, inputMax, maxSamples) {
@@ -117,46 +114,57 @@ function generateSampleIndices(inputMin, inputMax, maxSamples) {
117
114
  return indices;
118
115
  }
119
116
 
120
- function MeasureColumnWidths(_ref2) {
121
- var columns = _ref2.columns,
122
- rows = _ref2.rows,
123
- widths = _ref2.widths,
124
- isSelectable = _ref2.isSelectable,
125
- onWidthsChange = _ref2.onWidthsChange;
117
+ function MeasureColumnWidths(_ref) {
118
+ var columns = _ref.columns,
119
+ rows = _ref.rows,
120
+ widths = _ref.widths,
121
+ isSelectable = _ref.isSelectable,
122
+ onWidthsChange = _ref.onWidthsChange;
126
123
 
127
- var _useStyletron3 = (0, _index.useStyletron)(),
128
- _useStyletron4 = _slicedToArray(_useStyletron3, 1),
129
- css = _useStyletron4[0];
124
+ var _useStyletron = (0, _index.useStyletron)(),
125
+ _useStyletron2 = _slicedToArray(_useStyletron, 1),
126
+ css = _useStyletron2[0];
130
127
 
131
- var widthMap = React.useMemo(function () {
132
- return new Map();
133
- }, []);
128
+ var measurementCount = React.useRef(0);
129
+ var dimensionsCache = React.useRef(widths);
134
130
  var sampleSize = rows.length < MAX_SAMPLE_SIZE ? rows.length : MAX_SAMPLE_SIZE;
135
131
  var finishedMeasurementCount = (sampleSize + 1) * columns.length;
136
- var sampleIndexes = React.useMemo(function () {
137
- return generateSampleIndices(0, rows.length - 1, sampleSize);
132
+ var sampleRowIndicesByColumn = React.useMemo(function () {
133
+ measurementCount.current = 0;
134
+ dimensionsCache.current = widths;
135
+ var indices = generateSampleIndices(0, rows.length - 1, sampleSize);
136
+ return columns.map(function () {
137
+ return indices;
138
+ });
138
139
  }, [columns, rows, widths, sampleSize]);
139
- var handleDimensionsChange = React.useCallback(function (columnIndex, dimensions) {
140
- var nextWidth = Math.min(Math.max(columns[columnIndex].minWidth || 0, widthMap.get(columnIndex) || 0, dimensions.width + 1), columns[columnIndex].maxWidth || Infinity);
140
+ var handleDimensionsChange = React.useCallback(function (columnIndex, rowIndex, dimensions) {
141
+ if (dimensions.width === undefined) return;
141
142
 
142
- if (nextWidth !== widthMap.get(columnIndex)) {
143
- widthMap.set(columnIndex, nextWidth);
143
+ if (columns[columnIndex] === undefined || dimensionsCache.current[columnIndex] === undefined) {
144
+ return;
144
145
  }
145
146
 
146
- if ( // Refresh at 100% of done
147
- widthMap.size === columns.length || // ...50%
148
- widthMap.size === Math.floor(columns.length / 2) || // ...25%
149
- widthMap.size === Math.floor(columns.length / 4)) {
150
- onWidthsChange(Array.from(widthMap.values()));
147
+ measurementCount.current += 1;
148
+ var nextWidth = Math.min(Math.max(columns[columnIndex].minWidth || 0, dimensionsCache.current[columnIndex], dimensions.width + 1), columns[columnIndex].maxWidth || Infinity);
149
+
150
+ if (nextWidth !== dimensionsCache.current[columnIndex]) {
151
+ var nextWidths = _toConsumableArray(dimensionsCache.current);
152
+
153
+ nextWidths[columnIndex] = nextWidth;
154
+ dimensionsCache.current = nextWidths;
155
+ }
156
+
157
+ if (measurementCount.current >= finishedMeasurementCount) {
158
+ onWidthsChange(dimensionsCache.current);
151
159
  }
152
160
  }, [columns, finishedMeasurementCount, onWidthsChange]);
153
161
  var hiddenStyle = css({
154
162
  position: 'absolute',
155
163
  overflow: 'hidden',
156
164
  height: 0
157
- }); // Remove the measurement nodes after we are done updating our column width
165
+ });
158
166
 
159
- if (widthMap.size === columns.length) {
167
+ if (measurementCount.current >= finishedMeasurementCount) {
160
168
  return null;
161
169
  }
162
170
 
@@ -167,15 +175,45 @@ function MeasureColumnWidths(_ref2) {
167
175
  className: hiddenStyle,
168
176
  "aria-hidden": true,
169
177
  role: "none"
170
- }, columns.map(function (column, i) {
171
- return /*#__PURE__*/React.createElement(MeasureColumn, {
172
- key: column.title + i,
173
- column: column,
174
- rows: rows,
175
- isSelectable: isSelectable,
176
- onLayout: handleDimensionsChange,
177
- columnIndex: i,
178
- sampleIndexes: sampleIndexes
178
+ }, sampleRowIndicesByColumn.map(function (rowIndices, columnIndex) {
179
+ var Cell = columns[columnIndex].renderCell;
180
+ return rowIndices.map(function (rowIndex) {
181
+ return /*#__PURE__*/React.createElement(ElementMeasurer, {
182
+ key: "measure-".concat(columnIndex, "-").concat(rowIndex),
183
+ onDimensionsChange: function onDimensionsChange(dimensions) {
184
+ return handleDimensionsChange(columnIndex, rowIndex, dimensions);
185
+ },
186
+ item: /*#__PURE__*/React.createElement(Cell, {
187
+ value: columns[columnIndex].mapDataToValue(rows[rowIndex].data),
188
+ isMeasured: true,
189
+ onSelect: isSelectable && columnIndex === 0 ? function () {} : undefined,
190
+ x: columnIndex,
191
+ y: rowIndex
192
+ })
193
+ });
194
+ });
195
+ }), columns.map(function (column, columnIndex) {
196
+ return /*#__PURE__*/React.createElement(ElementMeasurer, {
197
+ key: "measure-column-".concat(columnIndex),
198
+ onDimensionsChange: function onDimensionsChange(dimensions) {
199
+ return handleDimensionsChange(columnIndex, -1, dimensions);
200
+ },
201
+ item: /*#__PURE__*/React.createElement(_headerCell.default, {
202
+ index: columnIndex,
203
+ isHovered: true,
204
+ isMeasured: true,
205
+ isSelectable: isSelectable && columnIndex === 0,
206
+ isSelectedAll: false,
207
+ isSelectedIndeterminate: false,
208
+ onMouseEnter: function onMouseEnter() {},
209
+ onMouseLeave: function onMouseLeave() {},
210
+ onSelectAll: function onSelectAll() {},
211
+ onSelectNone: function onSelectNone() {},
212
+ onSort: function onSort(i) {},
213
+ sortable: column.sortable,
214
+ sortDirection: null,
215
+ title: column.title
216
+ })
179
217
  });
180
218
  }))
181
219
  );
@@ -12,69 +12,46 @@ 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';
16
15
 
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();
16
+ // https://github.com/Swizec/useDimensions
17
+ function useDimensions() {
18
+ const [dimensions, setDimensions] = React.useState({});
19
+ const [node, setNode] = React.useState(null);
27
20
 
28
- const ref = useRef();
21
+ const ref = React.useCallback(node => {
22
+ setNode(node);
23
+ }, []);
29
24
 
30
25
  React.useEffect(() => {
31
- if (ref.current) {
32
- onLayout(columnIndex, ref.current.getBoundingClientRect());
26
+ if (__BROWSER__) {
27
+ if (node) {
28
+ window.requestAnimationFrame(() => {
29
+ setDimensions(node.getBoundingClientRect());
30
+ });
31
+ }
33
32
  }
34
- }, []);
33
+ }, [node]);
35
34
 
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
- );
35
+ return [ref, dimensions];
77
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]);
51
+
52
+ return React.cloneElement(props.item, {ref});
53
+ }
54
+
78
55
  type MeasureColumnWidthsPropsT = {
79
56
  columns: ColumnT<>[],
80
57
  // if selectable, measure the first column with checkbox included
@@ -84,6 +61,7 @@ type MeasureColumnWidthsPropsT = {
84
61
  widths: number[],
85
62
  };
86
63
 
64
+ // sample size could likely be generated based on row count, to have higher confidence
87
65
  const MAX_SAMPLE_SIZE = 50;
88
66
 
89
67
  function generateSampleIndices(inputMin, inputMax, maxSamples) {
@@ -118,41 +96,51 @@ export default function MeasureColumnWidths({
118
96
  }: MeasureColumnWidthsPropsT) {
119
97
  const [css] = useStyletron();
120
98
 
121
- const widthMap = React.useMemo(() => {
122
- return new Map();
123
- }, []);
99
+ const measurementCount = React.useRef(0);
100
+ const dimensionsCache = React.useRef(widths);
124
101
 
125
102
  const sampleSize =
126
103
  rows.length < MAX_SAMPLE_SIZE ? rows.length : MAX_SAMPLE_SIZE;
127
104
  const finishedMeasurementCount = (sampleSize + 1) * columns.length;
128
105
 
129
- const sampleIndexes = React.useMemo<number[]>(() => {
130
- return generateSampleIndices(0, rows.length - 1, sampleSize);
106
+ const sampleRowIndicesByColumn = React.useMemo<number[][]>(() => {
107
+ measurementCount.current = 0;
108
+ dimensionsCache.current = widths;
109
+
110
+ const indices = generateSampleIndices(0, rows.length - 1, sampleSize);
111
+ return columns.map(() => indices);
131
112
  }, [columns, rows, widths, sampleSize]);
132
113
 
133
114
  const handleDimensionsChange = React.useCallback(
134
- (columnIndex, dimensions) => {
115
+ (columnIndex, rowIndex, dimensions) => {
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
+
135
127
  const nextWidth = Math.min(
136
128
  Math.max(
137
129
  columns[columnIndex].minWidth || 0,
138
- widthMap.get(columnIndex) || 0,
130
+ dimensionsCache.current[columnIndex],
139
131
  dimensions.width + 1,
140
132
  ),
141
133
  columns[columnIndex].maxWidth || Infinity,
142
134
  );
143
135
 
144
- if (nextWidth !== widthMap.get(columnIndex)) {
145
- widthMap.set(columnIndex, nextWidth);
136
+ if (nextWidth !== dimensionsCache.current[columnIndex]) {
137
+ const nextWidths = [...dimensionsCache.current];
138
+ nextWidths[columnIndex] = nextWidth;
139
+ dimensionsCache.current = nextWidths;
146
140
  }
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()));
141
+
142
+ if (measurementCount.current >= finishedMeasurementCount) {
143
+ onWidthsChange(dimensionsCache.current);
156
144
  }
157
145
  },
158
146
  [columns, finishedMeasurementCount, onWidthsChange],
@@ -164,27 +152,61 @@ export default function MeasureColumnWidths({
164
152
  height: 0,
165
153
  });
166
154
 
167
- // Remove the measurement nodes after we are done updating our column width
168
- if (widthMap.size === columns.length) {
155
+ if (measurementCount.current >= finishedMeasurementCount) {
169
156
  return null;
170
157
  }
171
158
 
172
159
  return (
173
160
  // eslint-disable-next-line jsx-a11y/role-supports-aria-props
174
161
  <div className={hiddenStyle} aria-hidden role="none">
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}
162
+ {sampleRowIndicesByColumn.map((rowIndices, columnIndex) => {
163
+ const Cell = columns[columnIndex].renderCell;
164
+ return rowIndices.map(rowIndex => (
165
+ <ElementMeasurer
166
+ key={`measure-${columnIndex}-${rowIndex}`}
167
+ onDimensionsChange={dimensions =>
168
+ handleDimensionsChange(columnIndex, rowIndex, dimensions)
169
+ }
170
+ item={
171
+ <Cell
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
+ }
185
181
  />
186
- );
182
+ ));
187
183
  })}
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
+ ))}
188
210
  </div>
189
211
  );
190
212
  }