baseui 10.9.2 → 10.10.0

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.
@@ -17,15 +17,17 @@ var _index3 = require("../input/index.js");
17
17
 
18
18
  var _index4 = require("../styles/index.js");
19
19
 
20
- var _index5 = require("../typography/index.js");
21
-
22
20
  var _column = _interopRequireDefault(require("./column.js"));
23
21
 
24
22
  var _constants = require("./constants.js");
25
23
 
26
24
  var _filterShell = _interopRequireDefault(require("./filter-shell.js"));
27
25
 
28
- var _index6 = require("../locale/index.js");
26
+ var _index5 = require("../locale/index.js");
27
+
28
+ var _d2 = require("d3");
29
+
30
+ var _index6 = require("../slider/index.js");
29
31
 
30
32
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
33
 
@@ -41,14 +43,6 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
41
43
 
42
44
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
43
45
 
44
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
45
-
46
- 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."); }
47
-
48
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
49
-
50
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
51
-
52
46
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
53
47
 
54
48
  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."); }
@@ -106,291 +100,231 @@ function validateInput(input) {
106
100
  return Boolean(parseFloat(input)) || input === '' || input === '-';
107
101
  }
108
102
 
109
- function filterParamsToInitialState(filterParams) {
110
- if (filterParams) {
111
- if (filterParams.comparisons.length > 1) {
112
- if (filterParams.comparisons[0].operation === _constants.NUMERICAL_OPERATIONS.LT && filterParams.comparisons[1].operation === _constants.NUMERICAL_OPERATIONS.GT) {
113
- return {
114
- exclude: !filterParams.exclude,
115
- comparatorIndex: 0,
116
- operatorIndex: 4,
117
- right: filterParams.comparisons[1].value.toString(),
118
- left: filterParams.comparisons[0].value.toString()
119
- };
120
- }
121
- } else {
122
- var comparison = filterParams.comparisons[0];
123
-
124
- if (comparison.operation === _constants.NUMERICAL_OPERATIONS.LT) {
125
- return {
126
- exclude: filterParams.exclude,
127
- comparatorIndex: 0,
128
- operatorIndex: 0,
129
- left: '',
130
- right: comparison.value.toString()
131
- };
132
- } else if (comparison.operation === _constants.NUMERICAL_OPERATIONS.GT) {
133
- return {
134
- exclude: filterParams.exclude,
135
- comparatorIndex: 0,
136
- operatorIndex: 1,
137
- left: comparison.value.toString(),
138
- right: ''
139
- };
140
- } else if (comparison.operation === _constants.NUMERICAL_OPERATIONS.LTE) {
141
- return {
142
- exclude: filterParams.exclude,
143
- comparatorIndex: 0,
144
- operatorIndex: 2,
145
- left: '',
146
- right: comparison.value.toString()
147
- };
148
- } else if (comparison.operation === _constants.NUMERICAL_OPERATIONS.GTE) {
149
- return {
150
- exclude: filterParams.exclude,
151
- comparatorIndex: 0,
152
- operatorIndex: 3,
153
- left: comparison.value.toString(),
154
- right: ''
155
- };
156
- } else if (comparison.operation === _constants.NUMERICAL_OPERATIONS.EQ) {
157
- return {
158
- exclude: filterParams.exclude,
159
- comparatorIndex: 1,
160
- operatorIndex: 0,
161
- left: comparison.value.toString(),
162
- right: ''
163
- };
164
- }
165
- }
166
- }
167
-
168
- return {
169
- exclude: false,
170
- comparatorIndex: 0,
171
- operatorIndex: 0,
172
- left: '',
173
- right: ''
174
- };
175
- }
103
+ var bisect = (0, _d2.bisector)(function (d) {
104
+ return d.x0;
105
+ });
106
+ var Histogram = /*#__PURE__*/React.memo(function Histogram(_ref) {
107
+ var data = _ref.data,
108
+ lower = _ref.lower,
109
+ upper = _ref.upper,
110
+ isRange = _ref.isRange,
111
+ exclude = _ref.exclude,
112
+ precision = _ref.precision;
176
113
 
177
- function NumericalFilter(props) {
178
114
  var _useStyletron = (0, _index4.useStyletron)(),
179
115
  _useStyletron2 = _slicedToArray(_useStyletron, 2),
180
116
  css = _useStyletron2[0],
181
117
  theme = _useStyletron2[1];
182
118
 
183
- var locale = React.useContext(_index6.LocaleContext);
184
- var initialState = filterParamsToInitialState(props.filterParams);
119
+ var _React$useMemo = React.useMemo(function () {
120
+ var bins = (0, _d2.bin)().thresholds(Math.min(data.length, _constants.MAX_BIN_COUNT))(data);
121
+ var xScale = (0, _d2.scaleLinear)().domain([bins[0].x0, bins[bins.length - 1].x1]).range([0, _constants.HISTOGRAM_SIZE.width]).clamp(true);
122
+ var yScale = (0, _d2.scaleLinear)().domain([0, (0, _d2.max)(bins, function (d) {
123
+ return d.length;
124
+ })]).nice().range([_constants.HISTOGRAM_SIZE.height, 0]);
125
+ return {
126
+ bins: bins,
127
+ xScale: xScale,
128
+ yScale: yScale
129
+ };
130
+ }, [data]),
131
+ bins = _React$useMemo.bins,
132
+ xScale = _React$useMemo.xScale,
133
+ yScale = _React$useMemo.yScale; // We need to find the index of bar which is nearest to the given single value
185
134
 
186
- var _React$useState = React.useState(initialState.exclude),
187
- _React$useState2 = _slicedToArray(_React$useState, 2),
188
- exclude = _React$useState2[0],
189
- setExclude = _React$useState2[1];
190
135
 
191
- var _React$useState3 = React.useState(initialState.comparatorIndex),
192
- _React$useState4 = _slicedToArray(_React$useState3, 2),
193
- comparatorIndex = _React$useState4[0],
194
- setComparatorIndex = _React$useState4[1];
136
+ var singleIndexNearest = React.useMemo(function () {
137
+ if (isRange) {
138
+ return null;
139
+ }
195
140
 
196
- var _React$useState5 = React.useState(initialState.operatorIndex),
197
- _React$useState6 = _slicedToArray(_React$useState5, 2),
198
- operatorIndex = _React$useState6[0],
199
- setOperatorIndex = _React$useState6[1];
141
+ return bisect.center(bins, lower);
142
+ }, [isRange, data, lower, upper]);
143
+ return /*#__PURE__*/React.createElement("div", {
144
+ className: css({
145
+ display: 'flex',
146
+ marginTop: theme.sizing.scale600,
147
+ marginLeft: theme.sizing.scale200,
148
+ marginRight: 0,
149
+ marginBottom: theme.sizing.scale400,
150
+ justifyContent: 'space-between',
151
+ overflow: 'visible'
152
+ })
153
+ }, /*#__PURE__*/React.createElement("svg", _constants.HISTOGRAM_SIZE, bins.map(function (d, index) {
154
+ var x = xScale(d.x0) + 1;
155
+ var y = yScale(d.length);
156
+ var width = Math.max(0, xScale(d.x1) - xScale(d.x0) - 1);
157
+ var height = yScale(0) - yScale(d.length);
158
+ var included;
159
+
160
+ if (singleIndexNearest != null) {
161
+ included = index === singleIndexNearest;
162
+ } else {
163
+ var withinLower = d.x1 > lower;
164
+ var withinUpper = d.x0 <= upper;
165
+ included = withinLower && withinUpper;
166
+ }
200
167
 
201
- var _React$useState7 = React.useState(initialState.left),
202
- _React$useState8 = _slicedToArray(_React$useState7, 2),
203
- left = _React$useState8[0],
204
- setLeft = _React$useState8[1];
168
+ if (exclude) {
169
+ included = !included;
170
+ }
205
171
 
206
- var _React$useState9 = React.useState(initialState.right),
207
- _React$useState10 = _slicedToArray(_React$useState9, 2),
208
- right = _React$useState10[0],
209
- setRight = _React$useState10[1];
172
+ return /*#__PURE__*/React.createElement("rect", {
173
+ key: "bar-".concat(index),
174
+ fill: included ? theme.colors.primary : theme.colors.mono400,
175
+ x: x,
176
+ y: y,
177
+ width: width,
178
+ height: height
179
+ });
180
+ })));
181
+ });
210
182
 
211
- var isRange = comparatorIndex === 0;
212
- var min = React.useMemo(function () {
213
- return Math.min.apply(Math, _toConsumableArray(props.data));
214
- }, [props.data]);
215
- var max = React.useMemo(function () {
216
- return Math.max.apply(Math, _toConsumableArray(props.data));
217
- }, [props.data]);
218
- React.useEffect(function () {
219
- if (!left) {
220
- setLeft(min.toString());
221
- }
183
+ function NumericalFilter(props) {
184
+ var _useStyletron3 = (0, _index4.useStyletron)(),
185
+ _useStyletron4 = _slicedToArray(_useStyletron3, 2),
186
+ css = _useStyletron4[0],
187
+ theme = _useStyletron4[1];
222
188
 
223
- if (!right) {
224
- setRight(max.toString());
225
- }
226
- }, []);
189
+ var locale = React.useContext(_index5.LocaleContext);
190
+ var precision = props.options.precision; // The state handling of this component could be refactored and cleaned up if we used useReducer.
227
191
 
228
- var _React$useMemo = React.useMemo(function () {
229
- if (!isRange) return [false, false];
192
+ var initialState = React.useMemo(function () {
193
+ return props.filterParams || {
194
+ exclude: false,
195
+ excludeKind: 'range',
196
+ comparatorIndex: 0,
197
+ lowerValue: null,
198
+ upperValue: null
199
+ };
200
+ }, [props.filterParams]);
230
201
 
231
- switch (operatorIndex) {
232
- case 4:
233
- return [false, false];
202
+ var _React$useState = React.useState(initialState.exclude),
203
+ _React$useState2 = _slicedToArray(_React$useState, 2),
204
+ exclude = _React$useState2[0],
205
+ setExclude = _React$useState2[1]; // the api of our ButtonGroup forces these numerical indexes...
206
+ // TODO look into allowing semantic names, similar to the radio component. Tricky part would be backwards compat
234
207
 
235
- case 0:
236
- case 2:
237
- return [true, false];
238
208
 
239
- case 1:
240
- case 3:
241
- return [false, true];
209
+ var _React$useState3 = React.useState(function () {
210
+ switch (initialState.excludeKind) {
211
+ case 'value':
212
+ return 1;
242
213
 
214
+ case 'range':
243
215
  default:
244
- return [true, true];
245
- }
246
- }, [operatorIndex, isRange]),
247
- _React$useMemo2 = _slicedToArray(_React$useMemo, 2),
248
- leftDisabled = _React$useMemo2[0],
249
- rightDisabled = _React$useMemo2[1];
250
-
251
- var leftInputRef = React.useRef(null);
252
- var rightInputRef = React.useRef(null);
253
- React.useEffect(function () {
254
- if (!leftDisabled && leftInputRef.current) {
255
- leftInputRef.current.focus({
256
- preventScroll: true
257
- });
258
- } else if (!rightDisabled && rightInputRef.current) {
259
- rightInputRef.current.focus({
260
- preventScroll: true
261
- });
216
+ // fallthrough
217
+ return 0;
262
218
  }
263
- }, [leftDisabled, rightDisabled, comparatorIndex]);
264
- React.useEffect(function () {
265
- switch (operatorIndex) {
266
- case 4:
267
- default:
268
- break;
219
+ }),
220
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
221
+ comparatorIndex = _React$useState4[0],
222
+ setComparatorIndex = _React$useState4[1]; // We use the d3 function to get the extent as it's a little more robust to null, -Infinity, etc.
269
223
 
270
- case 1:
271
- case 3:
272
- setRight(max.toString());
273
- break;
274
224
 
275
- case 0:
276
- case 2:
277
- setLeft(min.toString());
278
- break;
279
- }
280
- }, [operatorIndex]);
225
+ var _React$useMemo2 = React.useMemo(function () {
226
+ return (0, _d2.extent)(props.data);
227
+ }, [props.data]),
228
+ _React$useMemo3 = _slicedToArray(_React$useMemo2, 2),
229
+ min = _React$useMemo3[0],
230
+ max = _React$useMemo3[1];
231
+
232
+ var _React$useState5 = React.useState(function () {
233
+ return roundToFixed(initialState.lowerValue || min, precision);
234
+ }),
235
+ _React$useState6 = _slicedToArray(_React$useState5, 2),
236
+ lv = _React$useState6[0],
237
+ setLower = _React$useState6[1];
238
+
239
+ var _React$useState7 = React.useState(function () {
240
+ return roundToFixed(initialState.upperValue || max, precision);
241
+ }),
242
+ _React$useState8 = _slicedToArray(_React$useState7, 2),
243
+ uv = _React$useState8[0],
244
+ setUpper = _React$useState8[1]; // We keep a separate value for the single select, to give a user the ability to toggle between
245
+ // the range and single values without losing their previous input.
246
+
247
+
248
+ var _React$useState9 = React.useState(function () {
249
+ return roundToFixed(initialState.lowerValue || (0, _d2.median)(props.data), precision);
250
+ }),
251
+ _React$useState10 = _slicedToArray(_React$useState9, 2),
252
+ sv = _React$useState10[0],
253
+ setSingle = _React$useState10[1]; // This is the only conditional which we want to use to determine
254
+ // if we are in range or single value mode.
255
+ // Don't derive it via something else, e.g. lowerValue === upperValue, etc.
256
+
257
+
258
+ var isRange = comparatorIndex === 0;
259
+ var excludeKind = isRange ? 'range' : 'value'; // while the user is inputting values, we take their input at face value,
260
+ // if we don't do this, a user can't input partial numbers, e.g. "-", or "3."
261
+
262
+ var _React$useState11 = React.useState(false),
263
+ _React$useState12 = _slicedToArray(_React$useState11, 2),
264
+ focused = _React$useState12[0],
265
+ setFocus = _React$useState12[1];
266
+
267
+ var _React$useMemo4 = React.useMemo(function () {
268
+ if (focused) {
269
+ return [isRange ? lv : sv, uv];
270
+ } // once the user is done inputting.
271
+ // we validate then format to the given precision
272
+
273
+
274
+ var l = isRange ? lv : sv;
275
+ l = validateInput(l) ? l : min;
276
+ var h = validateInput(uv) ? uv : max;
277
+ return [roundToFixed(l, precision), roundToFixed(h, precision)];
278
+ }, [isRange, focused, sv, lv, uv, precision]),
279
+ _React$useMemo5 = _slicedToArray(_React$useMemo4, 2),
280
+ inputValueLower = _React$useMemo5[0],
281
+ inputValueUpper = _React$useMemo5[1]; // We have our slider values range from 1 to the bin size, so we have a scale which
282
+ // takes in the data driven range and maps it to values the scale can always handle
283
+
284
+
285
+ var sliderScale = React.useMemo(function () {
286
+ return (0, _d2.scaleLinear)().domain([min, max]).rangeRound([1, _constants.MAX_BIN_COUNT]) // We clamp the values within our min and max even if a user enters a huge number
287
+ .clamp(true);
288
+ }, [min, max]);
289
+ var sliderValue = isRange ? [sliderScale(inputValueLower), sliderScale(inputValueUpper)] : [sliderScale(inputValueLower)]; // keep the slider happy by sorting the two values
290
+
291
+ if (isRange && sliderValue[0] > sliderValue[1]) {
292
+ sliderValue = [sliderValue[1], sliderValue[0]];
293
+ }
294
+
281
295
  return /*#__PURE__*/React.createElement(_filterShell.default, {
282
296
  exclude: exclude,
283
297
  onExcludeChange: function onExcludeChange() {
284
298
  return setExclude(!exclude);
285
299
  },
300
+ excludeKind: excludeKind,
286
301
  onApply: function onApply() {
287
302
  if (isRange) {
288
- switch (operatorIndex) {
289
- case 0:
290
- {
291
- var _value = parseFloat(right);
292
-
293
- var operation = _constants.NUMERICAL_OPERATIONS.LT;
294
- props.setFilter({
295
- comparisons: [{
296
- value: _value,
297
- operation: operation
298
- }],
299
- description: "< ".concat(_value),
300
- exclude: exclude
301
- });
302
- break;
303
- }
304
-
305
- case 1:
306
- {
307
- var _value2 = parseFloat(left);
308
-
309
- var _operation = _constants.NUMERICAL_OPERATIONS.GT;
310
- props.setFilter({
311
- comparisons: [{
312
- value: _value2,
313
- operation: _operation
314
- }],
315
- description: "> ".concat(_value2),
316
- exclude: exclude
317
- });
318
- break;
319
- }
320
-
321
- case 2:
322
- {
323
- var _value3 = parseFloat(right);
324
-
325
- var _operation2 = _constants.NUMERICAL_OPERATIONS.LTE;
326
- props.setFilter({
327
- comparisons: [{
328
- value: _value3,
329
- operation: _operation2
330
- }],
331
- description: "\u2264 ".concat(_value3),
332
- exclude: exclude
333
- });
334
- break;
335
- }
336
-
337
- case 3:
338
- {
339
- var _value4 = parseFloat(left);
340
-
341
- var _operation3 = _constants.NUMERICAL_OPERATIONS.GTE;
342
- props.setFilter({
343
- comparisons: [{
344
- value: _value4,
345
- operation: _operation3
346
- }],
347
- description: "\u2265 ".concat(_value4),
348
- exclude: exclude
349
- });
350
- break;
351
- }
352
-
353
- case 4:
354
- {
355
- // 'between' case is interesting since if we want less than 10 plus greater than 5
356
- // comparators, the filter will include _all_ numbers.
357
- var leftValue = parseFloat(left);
358
- var rightValue = parseFloat(right);
359
- props.setFilter({
360
- comparisons: [{
361
- value: leftValue,
362
- operation: _constants.NUMERICAL_OPERATIONS.LT
363
- }, {
364
- value: rightValue,
365
- operation: _constants.NUMERICAL_OPERATIONS.GT
366
- }],
367
- description: "\u2265 ".concat(leftValue, " & \u2264 ").concat(rightValue),
368
- exclude: !exclude
369
- });
370
- break;
371
- }
372
-
373
- default:
374
- break;
375
- }
303
+ var lowerValue = parseFloat(inputValueLower);
304
+ var upperValue = parseFloat(inputValueUpper);
305
+ props.setFilter({
306
+ description: "\u2265 ".concat(lowerValue, " and \u2264 ").concat(upperValue),
307
+ exclude: exclude,
308
+ lowerValue: lowerValue,
309
+ upperValue: upperValue,
310
+ excludeKind: excludeKind
311
+ });
376
312
  } else {
377
- var _value5 = parseFloat(left);
313
+ var _value = parseFloat(inputValueLower);
378
314
 
379
- var _operation4 = _constants.NUMERICAL_OPERATIONS.EQ;
380
315
  props.setFilter({
381
- comparisons: [{
382
- value: _value5,
383
- operation: _operation4
384
- }],
385
- description: "= ".concat(_value5),
386
- exclude: exclude
316
+ description: "= ".concat(_value),
317
+ exclude: exclude,
318
+ lowerValue: inputValueLower,
319
+ upperValue: inputValueLower,
320
+ excludeKind: excludeKind
387
321
  });
388
322
  }
389
323
 
390
324
  props.close();
391
325
  }
392
326
  }, /*#__PURE__*/React.createElement(_index2.ButtonGroup, {
393
- size: _index.SIZE.compact,
327
+ size: _index.SIZE.mini,
394
328
  mode: _index2.MODE.radio,
395
329
  selected: comparatorIndex,
396
330
  onClick: function onClick(_, index) {
@@ -398,8 +332,8 @@ function NumericalFilter(props) {
398
332
  },
399
333
  overrides: {
400
334
  Root: {
401
- style: function style(_ref) {
402
- var $theme = _ref.$theme;
335
+ style: function style(_ref2) {
336
+ var $theme = _ref2.$theme;
403
337
  return {
404
338
  marginBottom: $theme.sizing.scale300
405
339
  };
@@ -414,7 +348,8 @@ function NumericalFilter(props) {
414
348
  width: '100%'
415
349
  }
416
350
  }
417
- }
351
+ },
352
+ "aria-label": locale.datatable.numericalFilterRange
418
353
  }, locale.datatable.numericalFilterRange), /*#__PURE__*/React.createElement(_index.Button, {
419
354
  type: "button",
420
355
  overrides: {
@@ -423,123 +358,168 @@ function NumericalFilter(props) {
423
358
  width: '100%'
424
359
  }
425
360
  }
426
- }
427
- }, locale.datatable.numericalFilterSingleValue)), isRange && /*#__PURE__*/React.createElement(_index2.ButtonGroup, {
428
- size: _index.SIZE.compact,
429
- mode: _index2.MODE.radio,
430
- selected: operatorIndex,
431
- onClick: function onClick(_, index) {
432
- return setOperatorIndex(index);
361
+ },
362
+ "aria-label": locale.datatable.numericalFilterSingleValue
363
+ }, locale.datatable.numericalFilterSingleValue)), /*#__PURE__*/React.createElement(Histogram, {
364
+ data: props.data,
365
+ lower: inputValueLower,
366
+ upper: inputValueUpper,
367
+ isRange: isRange,
368
+ exclude: exclude,
369
+ precision: props.options.precision
370
+ }), /*#__PURE__*/React.createElement("div", {
371
+ className: css({
372
+ display: 'flex',
373
+ justifyContent: 'space-between'
374
+ })
375
+ }, /*#__PURE__*/React.createElement(_index6.Slider // The slider throws errors when switching between single and two values
376
+ // when it tries to read getThumbDistance on a thumb which is not there anymore
377
+ // if we create a new instance these errors are prevented.
378
+ , {
379
+ key: isRange.toString(),
380
+ min: 1,
381
+ max: _constants.MAX_BIN_COUNT,
382
+ value: sliderValue,
383
+ onChange: function onChange(_ref3) {
384
+ var value = _ref3.value;
385
+
386
+ if (!value) {
387
+ return;
388
+ } // we convert back from the slider scale to the actual data's scale
389
+
390
+
391
+ if (isRange) {
392
+ var _value2 = _slicedToArray(value, 2),
393
+ lowerValue = _value2[0],
394
+ upperValue = _value2[1];
395
+
396
+ setLower(sliderScale.invert(lowerValue));
397
+ setUpper(sliderScale.invert(upperValue));
398
+ } else {
399
+ var _value3 = _slicedToArray(value, 1),
400
+ singleValue = _value3[0];
401
+
402
+ setSingle(sliderScale.invert(singleValue));
403
+ }
433
404
  },
434
405
  overrides: {
406
+ InnerThumb: function InnerThumb(_ref4) {
407
+ var $value = _ref4.$value,
408
+ $thumbIndex = _ref4.$thumbIndex;
409
+ return /*#__PURE__*/React.createElement(React.Fragment, null, $value[$thumbIndex]);
410
+ },
411
+ TickBar: function TickBar(_ref5) {
412
+ var $min = _ref5.$min,
413
+ $max = _ref5.$max;
414
+ return null;
415
+ },
416
+ // we don't want the ticks
417
+ ThumbValue: function ThumbValue() {
418
+ return null;
419
+ },
435
420
  Root: {
436
- style: function style(_ref2) {
437
- var $theme = _ref2.$theme;
421
+ style: function style() {
438
422
  return {
439
- marginBottom: $theme.sizing.scale500
423
+ // Aligns the center of the slider handles with the histogram bars
424
+ width: 'calc(100% + 14px)',
425
+ margin: '0 -7px'
440
426
  };
441
427
  }
442
- }
443
- }
444
- }, /*#__PURE__*/React.createElement(_index.Button, {
445
- type: "button",
446
- overrides: {
447
- BaseButton: {
448
- style: {
449
- width: '100%'
450
- }
451
- }
452
- }
453
- }, "<"), /*#__PURE__*/React.createElement(_index.Button, {
454
- type: "button",
455
- overrides: {
456
- BaseButton: {
457
- style: {
458
- width: '100%'
459
- }
460
- }
461
- }
462
- }, ">"), /*#__PURE__*/React.createElement(_index.Button, {
463
- type: "button",
464
- overrides: {
465
- BaseButton: {
466
- style: {
467
- width: '100%'
468
- }
469
- }
470
- }
471
- }, "\u2264"), /*#__PURE__*/React.createElement(_index.Button, {
472
- type: "button",
473
- overrides: {
474
- BaseButton: {
475
- style: {
476
- width: '100%'
428
+ },
429
+ InnerTrack: {
430
+ style: function style(_ref6) {
431
+ var $theme = _ref6.$theme;
432
+
433
+ if (!isRange) {
434
+ return {
435
+ // For range selection we use the color as is, but when selecting the single value,
436
+ // we don't want the track standing out, so mute its color
437
+ background: theme.colors.mono400
438
+ };
439
+ }
477
440
  }
478
- }
479
- }
480
- }, "\u2265"), /*#__PURE__*/React.createElement(_index.Button, {
481
- type: "button",
482
- overrides: {
483
- BaseButton: {
484
- style: {
485
- width: '100%'
441
+ },
442
+ Thumb: {
443
+ style: function style() {
444
+ return {
445
+ // Slider handles are small enough to visually be centered within each histogram bar
446
+ height: '18px',
447
+ width: '18px',
448
+ fontSize: '0px'
449
+ };
486
450
  }
487
451
  }
488
452
  }
489
- }, "=")), /*#__PURE__*/React.createElement("div", {
490
- className: css({
491
- display: 'flex',
492
- justifyContent: 'space-between',
493
- marginLeft: theme.sizing.scale300,
494
- marginRight: theme.sizing.scale300
495
- })
496
- }, /*#__PURE__*/React.createElement(_index5.ParagraphXSmall, null, format(min, props.options)), ' ', /*#__PURE__*/React.createElement(_index5.ParagraphXSmall, null, format(max, props.options))), /*#__PURE__*/React.createElement("div", {
453
+ })), /*#__PURE__*/React.createElement("div", {
497
454
  className: css({
498
455
  display: 'flex',
456
+ marginTop: theme.sizing.scale400,
457
+ // This % gap is visually appealing given the filter box width
458
+ gap: '30%',
499
459
  justifyContent: 'space-between'
500
460
  })
501
461
  }, /*#__PURE__*/React.createElement(_index3.Input, {
502
- size: _index3.SIZE.compact,
462
+ min: min,
463
+ max: max,
464
+ size: _index3.SIZE.mini,
503
465
  overrides: {
504
466
  Root: {
505
467
  style: {
506
- width: isRange ? '152px' : '100%'
468
+ width: '100%'
507
469
  }
508
470
  }
509
471
  },
510
- disabled: leftDisabled,
511
- inputRef: leftInputRef,
512
- value: left,
472
+ value: inputValueLower,
513
473
  onChange: function onChange(event) {
514
474
  if (validateInput(event.target.value)) {
515
- setLeft(event.target.value);
475
+ isRange ? // $FlowFixMe - we know it is a number by now
476
+ setLower(event.target.value) : // $FlowFixMe - we know it is a number by now
477
+ setSingle(event.target.value);
516
478
  }
479
+ },
480
+ onFocus: function onFocus() {
481
+ return setFocus(true);
482
+ },
483
+ onBlur: function onBlur() {
484
+ return setFocus(false);
517
485
  }
518
486
  }), isRange && /*#__PURE__*/React.createElement(_index3.Input, {
519
- size: _index3.SIZE.compact,
487
+ min: min,
488
+ max: max,
489
+ size: _index3.SIZE.mini,
520
490
  overrides: {
491
+ Input: {
492
+ style: {
493
+ textAlign: 'right'
494
+ }
495
+ },
521
496
  Root: {
522
497
  style: {
523
- width: '152px'
498
+ width: '100%'
524
499
  }
525
500
  }
526
501
  },
527
- disabled: rightDisabled,
528
- inputRef: rightInputRef,
529
- value: right,
502
+ value: inputValueUpper,
530
503
  onChange: function onChange(event) {
531
504
  if (validateInput(event.target.value)) {
532
- setRight(event.target.value);
505
+ // $FlowFixMe - we know it is a number by now
506
+ setUpper(event.target.value);
533
507
  }
508
+ },
509
+ onFocus: function onFocus() {
510
+ return setFocus(true);
511
+ },
512
+ onBlur: function onBlur() {
513
+ return setFocus(false);
534
514
  }
535
515
  })));
536
516
  }
537
517
 
538
518
  function NumericalCell(props) {
539
- var _useStyletron3 = (0, _index4.useStyletron)(),
540
- _useStyletron4 = _slicedToArray(_useStyletron3, 2),
541
- css = _useStyletron4[0],
542
- theme = _useStyletron4[1];
519
+ var _useStyletron5 = (0, _index4.useStyletron)(),
520
+ _useStyletron6 = _slicedToArray(_useStyletron5, 2),
521
+ css = _useStyletron6[0],
522
+ theme = _useStyletron6[1];
543
523
 
544
524
  return /*#__PURE__*/React.createElement("div", {
545
525
  className: css(_objectSpread(_objectSpread({}, theme.typography.MonoParagraphXSmall), {}, {
@@ -582,30 +562,8 @@ function NumericalColumn(options) {
582
562
  kind: _constants.COLUMNS.NUMERICAL,
583
563
  buildFilter: function buildFilter(params) {
584
564
  return function (data) {
585
- var included = params.comparisons.some(function (c) {
586
- var left = roundToFixed(data, normalizedOptions.precision);
587
- var right = roundToFixed(c.value, normalizedOptions.precision);
588
-
589
- switch (c.operation) {
590
- case _constants.NUMERICAL_OPERATIONS.EQ:
591
- return left === right;
592
-
593
- case _constants.NUMERICAL_OPERATIONS.GT:
594
- return left > right;
595
-
596
- case _constants.NUMERICAL_OPERATIONS.GTE:
597
- return left >= right;
598
-
599
- case _constants.NUMERICAL_OPERATIONS.LT:
600
- return left < right;
601
-
602
- case _constants.NUMERICAL_OPERATIONS.LTE:
603
- return left <= right;
604
-
605
- default:
606
- return true;
607
- }
608
- });
565
+ var value = roundToFixed(data, normalizedOptions.precision);
566
+ var included = value >= params.lowerValue && value <= params.upperValue;
609
567
  return params.exclude ? !included : included;
610
568
  };
611
569
  },