baseui 10.8.0 → 10.9.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.
Files changed (170) hide show
  1. package/a11y/a11y.js +2 -2
  2. package/a11y/a11y.js.flow +3 -3
  3. package/button/styled-components.js +47 -18
  4. package/button/styled-components.js.flow +25 -5
  5. package/combobox/combobox.js +6 -3
  6. package/combobox/combobox.js.flow +4 -2
  7. package/combobox/types.js.flow +2 -0
  8. package/data-table/column-categorical.js +1 -1
  9. package/data-table/column-categorical.js.flow +2 -2
  10. package/data-table/column-numerical.js +307 -355
  11. package/data-table/column-numerical.js.flow +273 -287
  12. package/data-table/constants.js +17 -11
  13. package/data-table/constants.js.flow +11 -8
  14. package/data-table/data-table.js +53 -50
  15. package/data-table/data-table.js.flow +18 -13
  16. package/data-table/filter-shell.js +27 -4
  17. package/data-table/filter-shell.js.flow +33 -9
  18. package/data-table/locale.js +4 -2
  19. package/data-table/locale.js.flow +6 -2
  20. package/data-table/measure-column-widths.js +83 -121
  21. package/data-table/measure-column-widths.js.flow +87 -109
  22. package/datepicker/styled-components.js +1 -1
  23. package/datepicker/styled-components.js.flow +4 -1
  24. package/drawer/drawer.js +3 -1
  25. package/drawer/drawer.js.flow +7 -1
  26. package/es/a11y/a11y.js +2 -2
  27. package/es/button/styled-components.js +32 -2
  28. package/es/combobox/combobox.js +6 -3
  29. package/es/data-table/column-categorical.js +2 -2
  30. package/es/data-table/column-numerical.js +245 -317
  31. package/es/data-table/constants.js +12 -8
  32. package/es/data-table/data-table.js +18 -16
  33. package/es/data-table/filter-shell.js +26 -4
  34. package/es/data-table/locale.js +4 -2
  35. package/es/data-table/measure-column-widths.js +75 -86
  36. package/es/datepicker/styled-components.js +1 -1
  37. package/es/drawer/drawer.js +3 -1
  38. package/es/index.js +1 -1
  39. package/es/map-marker/badge-enhancer.js +61 -0
  40. package/es/map-marker/constants.js +146 -2
  41. package/es/map-marker/drag-shadow.js +32 -0
  42. package/es/map-marker/fixed-marker.js +54 -48
  43. package/es/map-marker/floating-marker.js +21 -12
  44. package/es/map-marker/index.js +1 -1
  45. package/es/map-marker/label-enhancer.js +39 -0
  46. package/es/map-marker/needle.js +26 -0
  47. package/es/map-marker/pin-head.js +42 -40
  48. package/es/map-marker/styled-components.js +177 -32
  49. package/es/map-marker/types.js +1 -1
  50. package/es/menu/maybe-child-menu.js +0 -2
  51. package/es/menu/nested-menus.js +49 -3
  52. package/es/menu/stateful-container.js +13 -12
  53. package/es/modal/modal.js +3 -1
  54. package/es/popover/popover.js +3 -1
  55. package/es/progress-bar/index.js +1 -1
  56. package/es/progress-bar/progressbar.js +25 -10
  57. package/es/progress-bar/styled-components.js +9 -5
  58. package/es/select/select-component.js +2 -10
  59. package/es/spinner/styled-components.js +34 -16
  60. package/es/table/filter.js +3 -1
  61. package/es/themes/dark-theme/color-component-tokens.js +4 -0
  62. package/es/themes/light-theme/color-component-tokens.js +4 -0
  63. package/es/timezonepicker/timezone-picker.js +53 -36
  64. package/es/timezonepicker/tzdata.js +2 -0
  65. package/es/timezonepicker/update-tzdata.js +69 -0
  66. package/esm/a11y/a11y.js +3 -3
  67. package/esm/button/styled-components.js +47 -18
  68. package/esm/combobox/combobox.js +6 -3
  69. package/esm/data-table/column-categorical.js +2 -2
  70. package/esm/data-table/column-numerical.js +304 -353
  71. package/esm/data-table/constants.js +12 -8
  72. package/esm/data-table/data-table.js +53 -50
  73. package/esm/data-table/filter-shell.js +26 -4
  74. package/esm/data-table/locale.js +4 -2
  75. package/esm/data-table/measure-column-widths.js +83 -121
  76. package/esm/datepicker/styled-components.js +1 -1
  77. package/esm/drawer/drawer.js +3 -1
  78. package/esm/index.js +1 -1
  79. package/esm/map-marker/badge-enhancer.js +79 -0
  80. package/esm/map-marker/constants.js +94 -4
  81. package/esm/map-marker/drag-shadow.js +53 -0
  82. package/esm/map-marker/fixed-marker.js +84 -80
  83. package/esm/map-marker/floating-marker.js +22 -13
  84. package/esm/map-marker/index.js +1 -1
  85. package/esm/map-marker/label-enhancer.js +60 -0
  86. package/esm/map-marker/needle.js +43 -0
  87. package/esm/map-marker/pin-head.js +77 -66
  88. package/esm/map-marker/styled-components.js +182 -51
  89. package/esm/map-marker/types.js +1 -1
  90. package/esm/menu/maybe-child-menu.js +0 -2
  91. package/esm/menu/nested-menus.js +66 -5
  92. package/esm/menu/stateful-container.js +15 -13
  93. package/esm/modal/modal.js +3 -1
  94. package/esm/popover/popover.js +3 -1
  95. package/esm/progress-bar/index.js +1 -1
  96. package/esm/progress-bar/progressbar.js +32 -10
  97. package/esm/progress-bar/styled-components.js +9 -4
  98. package/esm/select/select-component.js +2 -11
  99. package/esm/spinner/styled-components.js +35 -16
  100. package/esm/table/filter.js +3 -1
  101. package/esm/themes/dark-theme/color-component-tokens.js +4 -0
  102. package/esm/themes/light-theme/color-component-tokens.js +4 -0
  103. package/esm/timezonepicker/timezone-picker.js +64 -36
  104. package/esm/timezonepicker/tzdata.js +2 -0
  105. package/esm/timezonepicker/update-tzdata.js +160 -0
  106. package/index.js +6 -0
  107. package/index.js.flow +1 -1
  108. package/map-marker/badge-enhancer.js +90 -0
  109. package/map-marker/badge-enhancer.js.flow +86 -0
  110. package/map-marker/constants.js +103 -5
  111. package/map-marker/constants.js.flow +152 -0
  112. package/map-marker/drag-shadow.js +64 -0
  113. package/map-marker/drag-shadow.js.flow +52 -0
  114. package/map-marker/fixed-marker.js +84 -78
  115. package/map-marker/fixed-marker.js.flow +78 -66
  116. package/map-marker/floating-marker.js +22 -13
  117. package/map-marker/floating-marker.js.flow +30 -17
  118. package/map-marker/index.d.ts +125 -24
  119. package/map-marker/index.js +18 -0
  120. package/map-marker/index.js.flow +3 -0
  121. package/map-marker/label-enhancer.js +71 -0
  122. package/map-marker/label-enhancer.js.flow +63 -0
  123. package/map-marker/needle.js +54 -0
  124. package/map-marker/needle.js.flow +29 -0
  125. package/map-marker/pin-head.js +80 -69
  126. package/map-marker/pin-head.js.flow +122 -84
  127. package/map-marker/styled-components.js +200 -62
  128. package/map-marker/styled-components.js.flow +172 -22
  129. package/map-marker/types.js.flow +69 -20
  130. package/menu/index.d.ts +9 -4
  131. package/menu/maybe-child-menu.js +0 -2
  132. package/menu/maybe-child-menu.js.flow +0 -2
  133. package/menu/nested-menus.js +66 -5
  134. package/menu/nested-menus.js.flow +50 -5
  135. package/menu/stateful-container.js +15 -13
  136. package/menu/stateful-container.js.flow +19 -13
  137. package/menu/types.js.flow +7 -1
  138. package/modal/modal.js +3 -1
  139. package/modal/modal.js.flow +2 -0
  140. package/package.json +5 -4
  141. package/popover/popover.js +3 -1
  142. package/popover/popover.js.flow +2 -0
  143. package/progress-bar/index.d.ts +2 -0
  144. package/progress-bar/index.js +6 -0
  145. package/progress-bar/index.js.flow +1 -0
  146. package/progress-bar/progressbar.js +32 -10
  147. package/progress-bar/progressbar.js.flow +35 -9
  148. package/progress-bar/styled-components.js +9 -4
  149. package/progress-bar/styled-components.js.flow +15 -4
  150. package/progress-bar/types.js.flow +12 -2
  151. package/select/select-component.js +2 -11
  152. package/select/select-component.js.flow +5 -7
  153. package/spinner/styled-components.js +35 -16
  154. package/spinner/styled-components.js.flow +37 -19
  155. package/spinner/types.js.flow +10 -0
  156. package/styles/index.js.flow +1 -1
  157. package/table/filter.js +3 -1
  158. package/table/filter.js.flow +5 -1
  159. package/themes/dark-theme/color-component-tokens.js +4 -0
  160. package/themes/dark-theme/color-component-tokens.js.flow +4 -0
  161. package/themes/light-theme/color-component-tokens.js +4 -0
  162. package/themes/light-theme/color-component-tokens.js.flow +4 -0
  163. package/themes/types.js.flow +4 -0
  164. package/timezonepicker/timezone-picker.js +69 -41
  165. package/timezonepicker/timezone-picker.js.flow +52 -46
  166. package/timezonepicker/types.js.flow +1 -1
  167. package/timezonepicker/tzdata.js +10 -0
  168. package/timezonepicker/tzdata.js.flow +347 -0
  169. package/timezonepicker/update-tzdata.js +164 -0
  170. package/timezonepicker/update-tzdata.js.flow +70 -0
@@ -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,226 @@ 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
134
+
135
+
136
+ var singleIndexNearest = React.useMemo(function () {
137
+ if (isRange) {
138
+ return null;
139
+ }
140
+
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
+ }
167
+
168
+ if (exclude) {
169
+ included = !included;
170
+ }
171
+
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
+ });
182
+
183
+ function NumericalFilter(props) {
184
+ var _useStyletron3 = (0, _index4.useStyletron)(),
185
+ _useStyletron4 = _slicedToArray(_useStyletron3, 2),
186
+ css = _useStyletron4[0],
187
+ theme = _useStyletron4[1];
188
+
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.
191
+
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]);
185
201
 
186
202
  var _React$useState = React.useState(initialState.exclude),
187
203
  _React$useState2 = _slicedToArray(_React$useState, 2),
188
204
  exclude = _React$useState2[0],
189
- setExclude = _React$useState2[1];
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
207
+
190
208
 
191
- var _React$useState3 = React.useState(initialState.comparatorIndex),
209
+ var _React$useState3 = React.useState(function () {
210
+ switch (initialState.excludeKind) {
211
+ case 'value':
212
+ return 1;
213
+
214
+ case 'range':
215
+ default:
216
+ // fallthrough
217
+ return 0;
218
+ }
219
+ }),
192
220
  _React$useState4 = _slicedToArray(_React$useState3, 2),
193
221
  comparatorIndex = _React$useState4[0],
194
- setComparatorIndex = _React$useState4[1];
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.
223
+
224
+
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];
195
231
 
196
- var _React$useState5 = React.useState(initialState.operatorIndex),
232
+ var _React$useState5 = React.useState(function () {
233
+ return roundToFixed(initialState.lowerValue || min, precision);
234
+ }),
197
235
  _React$useState6 = _slicedToArray(_React$useState5, 2),
198
- operatorIndex = _React$useState6[0],
199
- setOperatorIndex = _React$useState6[1];
236
+ lv = _React$useState6[0],
237
+ setLower = _React$useState6[1];
200
238
 
201
- var _React$useState7 = React.useState(initialState.left),
239
+ var _React$useState7 = React.useState(function () {
240
+ return roundToFixed(initialState.upperValue || max, precision);
241
+ }),
202
242
  _React$useState8 = _slicedToArray(_React$useState7, 2),
203
- left = _React$useState8[0],
204
- setLeft = _React$useState8[1];
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.
205
246
 
206
- var _React$useState9 = React.useState(initialState.right),
247
+
248
+ var _React$useState9 = React.useState(function () {
249
+ return roundToFixed(initialState.lowerValue || (0, _d2.median)(props.data), precision);
250
+ }),
207
251
  _React$useState10 = _slicedToArray(_React$useState9, 2),
208
- right = _React$useState10[0],
209
- setRight = _React$useState10[1];
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
+
210
257
 
211
258
  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
- }
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."
222
261
 
223
- if (!right) {
224
- setRight(max.toString());
225
- }
226
- }, []);
262
+ var _React$useState11 = React.useState(false),
263
+ _React$useState12 = _slicedToArray(_React$useState11, 2),
264
+ focused = _React$useState12[0],
265
+ setFocus = _React$useState12[1];
227
266
 
228
- var _React$useMemo = React.useMemo(function () {
229
- if (!isRange) return [false, false];
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
230
272
 
231
- switch (operatorIndex) {
232
- case 4:
233
- return [false, false];
234
273
 
235
- case 0:
236
- case 2:
237
- return [true, false];
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 bound the values within our min and max even if a user enters a huge number
238
282
 
239
- case 1:
240
- case 3:
241
- return [false, true];
242
283
 
243
- 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
- });
262
- }
263
- }, [leftDisabled, rightDisabled, comparatorIndex]);
264
- React.useEffect(function () {
265
- switch (operatorIndex) {
266
- case 4:
267
- default:
268
- break;
284
+ var sliderValue = isRange ? [Math.max(inputValueLower, min), Math.min(inputValueUpper, max)] : [Math.min(Math.max(inputValueLower, min), max)]; // keep the slider happy by sorting the two values
269
285
 
270
- case 1:
271
- case 3:
272
- setRight(max.toString());
273
- break;
286
+ if (isRange && sliderValue[0] > sliderValue[1]) {
287
+ sliderValue = [sliderValue[1], sliderValue[0]];
288
+ }
274
289
 
275
- case 0:
276
- case 2:
277
- setLeft(min.toString());
278
- break;
279
- }
280
- }, [operatorIndex]);
281
290
  return /*#__PURE__*/React.createElement(_filterShell.default, {
282
291
  exclude: exclude,
283
292
  onExcludeChange: function onExcludeChange() {
284
293
  return setExclude(!exclude);
285
294
  },
295
+ excludeKind: excludeKind,
286
296
  onApply: function onApply() {
287
297
  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
- }
298
+ var lowerValue = parseFloat(inputValueLower);
299
+ var upperValue = parseFloat(inputValueUpper);
300
+ props.setFilter({
301
+ description: "\u2265 ".concat(lowerValue, " and \u2264 ").concat(upperValue),
302
+ exclude: exclude,
303
+ lowerValue: lowerValue,
304
+ upperValue: upperValue,
305
+ excludeKind: excludeKind
306
+ });
376
307
  } else {
377
- var _value5 = parseFloat(left);
308
+ var _value = parseFloat(inputValueLower);
378
309
 
379
- var _operation4 = _constants.NUMERICAL_OPERATIONS.EQ;
380
310
  props.setFilter({
381
- comparisons: [{
382
- value: _value5,
383
- operation: _operation4
384
- }],
385
- description: "= ".concat(_value5),
386
- exclude: exclude
311
+ description: "= ".concat(_value),
312
+ exclude: exclude,
313
+ lowerValue: inputValueLower,
314
+ upperValue: inputValueLower,
315
+ excludeKind: excludeKind
387
316
  });
388
317
  }
389
318
 
390
319
  props.close();
391
320
  }
392
321
  }, /*#__PURE__*/React.createElement(_index2.ButtonGroup, {
393
- size: _index.SIZE.compact,
322
+ size: _index.SIZE.mini,
394
323
  mode: _index2.MODE.radio,
395
324
  selected: comparatorIndex,
396
325
  onClick: function onClick(_, index) {
@@ -398,8 +327,8 @@ function NumericalFilter(props) {
398
327
  },
399
328
  overrides: {
400
329
  Root: {
401
- style: function style(_ref) {
402
- var $theme = _ref.$theme;
330
+ style: function style(_ref2) {
331
+ var $theme = _ref2.$theme;
403
332
  return {
404
333
  marginBottom: $theme.sizing.scale300
405
334
  };
@@ -414,7 +343,8 @@ function NumericalFilter(props) {
414
343
  width: '100%'
415
344
  }
416
345
  }
417
- }
346
+ },
347
+ "aria-label": locale.datatable.numericalFilterRange
418
348
  }, locale.datatable.numericalFilterRange), /*#__PURE__*/React.createElement(_index.Button, {
419
349
  type: "button",
420
350
  overrides: {
@@ -423,123 +353,167 @@ function NumericalFilter(props) {
423
353
  width: '100%'
424
354
  }
425
355
  }
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);
356
+ },
357
+ "aria-label": locale.datatable.numericalFilterSingleValue
358
+ }, locale.datatable.numericalFilterSingleValue)), /*#__PURE__*/React.createElement(Histogram, {
359
+ data: props.data,
360
+ lower: inputValueLower,
361
+ upper: inputValueUpper,
362
+ isRange: isRange,
363
+ exclude: exclude,
364
+ precision: props.options.precision
365
+ }), /*#__PURE__*/React.createElement("div", {
366
+ className: css({
367
+ display: 'flex',
368
+ justifyContent: 'space-between'
369
+ })
370
+ }, /*#__PURE__*/React.createElement(_index6.Slider // The slider throws errors when switching between single and two values
371
+ // when it tries to read getThumbDistance on a thumb which is not there anymore
372
+ // if we create a new instance these errors are prevented.
373
+ , {
374
+ key: isRange.toString(),
375
+ min: min,
376
+ max: max,
377
+ value: sliderValue,
378
+ onChange: function onChange(_ref3) {
379
+ var value = _ref3.value;
380
+
381
+ if (!value) {
382
+ return;
383
+ }
384
+
385
+ if (isRange) {
386
+ var _value2 = _slicedToArray(value, 2),
387
+ lowerValue = _value2[0],
388
+ upperValue = _value2[1];
389
+
390
+ setLower(lowerValue);
391
+ setUpper(upperValue);
392
+ } else {
393
+ var _value3 = _slicedToArray(value, 1),
394
+ singleValue = _value3[0];
395
+
396
+ setSingle(singleValue);
397
+ }
433
398
  },
434
399
  overrides: {
400
+ InnerThumb: function InnerThumb(_ref4) {
401
+ var $value = _ref4.$value,
402
+ $thumbIndex = _ref4.$thumbIndex;
403
+ return /*#__PURE__*/React.createElement(React.Fragment, null, $value[$thumbIndex]);
404
+ },
405
+ TickBar: function TickBar(_ref5) {
406
+ var $min = _ref5.$min,
407
+ $max = _ref5.$max;
408
+ return null;
409
+ },
410
+ // we don't want the ticks
411
+ ThumbValue: function ThumbValue() {
412
+ return null;
413
+ },
435
414
  Root: {
436
- style: function style(_ref2) {
437
- var $theme = _ref2.$theme;
415
+ style: function style() {
438
416
  return {
439
- marginBottom: $theme.sizing.scale500
417
+ // Aligns the center of the slider handles with the histogram bars
418
+ width: 'calc(100% + 14px)',
419
+ margin: '0 -7px'
440
420
  };
441
421
  }
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%'
422
+ },
423
+ InnerTrack: {
424
+ style: function style(_ref6) {
425
+ var $theme = _ref6.$theme;
426
+
427
+ if (!isRange) {
428
+ return {
429
+ // For range selection we use the color as is, but when selecting the single value,
430
+ // we don't want the track standing out, so mute its color
431
+ background: theme.colors.mono400
432
+ };
433
+ }
477
434
  }
478
- }
479
- }
480
- }, "\u2265"), /*#__PURE__*/React.createElement(_index.Button, {
481
- type: "button",
482
- overrides: {
483
- BaseButton: {
484
- style: {
485
- width: '100%'
435
+ },
436
+ Thumb: {
437
+ style: function style() {
438
+ return {
439
+ // Slider handles are small enough to visually be centered within each histogram bar
440
+ height: '18px',
441
+ width: '18px',
442
+ fontSize: '0px'
443
+ };
486
444
  }
487
445
  }
488
446
  }
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.Paragraph4, null, format(min, props.options)), ' ', /*#__PURE__*/React.createElement(_index5.Paragraph4, null, format(max, props.options))), /*#__PURE__*/React.createElement("div", {
447
+ })), /*#__PURE__*/React.createElement("div", {
497
448
  className: css({
498
449
  display: 'flex',
450
+ marginTop: theme.sizing.scale400,
451
+ // This % gap is visually appealing given the filter box width
452
+ gap: '30%',
499
453
  justifyContent: 'space-between'
500
454
  })
501
455
  }, /*#__PURE__*/React.createElement(_index3.Input, {
502
- size: _index3.SIZE.compact,
456
+ min: min,
457
+ max: max,
458
+ size: _index3.SIZE.mini,
503
459
  overrides: {
504
460
  Root: {
505
461
  style: {
506
- width: isRange ? '152px' : '100%'
462
+ width: '100%'
507
463
  }
508
464
  }
509
465
  },
510
- disabled: leftDisabled,
511
- inputRef: leftInputRef,
512
- value: left,
466
+ value: inputValueLower,
513
467
  onChange: function onChange(event) {
514
468
  if (validateInput(event.target.value)) {
515
- setLeft(event.target.value);
469
+ isRange ? // $FlowFixMe - we know it is a number by now
470
+ setLower(event.target.value) : // $FlowFixMe - we know it is a number by now
471
+ setSingle(event.target.value);
516
472
  }
473
+ },
474
+ onFocus: function onFocus() {
475
+ return setFocus(true);
476
+ },
477
+ onBlur: function onBlur() {
478
+ return setFocus(false);
517
479
  }
518
480
  }), isRange && /*#__PURE__*/React.createElement(_index3.Input, {
519
- size: _index3.SIZE.compact,
481
+ min: min,
482
+ max: max,
483
+ size: _index3.SIZE.mini,
520
484
  overrides: {
485
+ Input: {
486
+ style: {
487
+ textAlign: 'right'
488
+ }
489
+ },
521
490
  Root: {
522
491
  style: {
523
- width: '152px'
492
+ width: '100%'
524
493
  }
525
494
  }
526
495
  },
527
- disabled: rightDisabled,
528
- inputRef: rightInputRef,
529
- value: right,
496
+ value: inputValueUpper,
530
497
  onChange: function onChange(event) {
531
498
  if (validateInput(event.target.value)) {
532
- setRight(event.target.value);
499
+ // $FlowFixMe - we know it is a number by now
500
+ setUpper(event.target.value);
533
501
  }
502
+ },
503
+ onFocus: function onFocus() {
504
+ return setFocus(true);
505
+ },
506
+ onBlur: function onBlur() {
507
+ return setFocus(false);
534
508
  }
535
509
  })));
536
510
  }
537
511
 
538
512
  function NumericalCell(props) {
539
- var _useStyletron3 = (0, _index4.useStyletron)(),
540
- _useStyletron4 = _slicedToArray(_useStyletron3, 2),
541
- css = _useStyletron4[0],
542
- theme = _useStyletron4[1];
513
+ var _useStyletron5 = (0, _index4.useStyletron)(),
514
+ _useStyletron6 = _slicedToArray(_useStyletron5, 2),
515
+ css = _useStyletron6[0],
516
+ theme = _useStyletron6[1];
543
517
 
544
518
  return /*#__PURE__*/React.createElement("div", {
545
519
  className: css(_objectSpread(_objectSpread({}, theme.typography.MonoParagraphXSmall), {}, {
@@ -582,30 +556,8 @@ function NumericalColumn(options) {
582
556
  kind: _constants.COLUMNS.NUMERICAL,
583
557
  buildFilter: function buildFilter(params) {
584
558
  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
- });
559
+ var value = roundToFixed(data, normalizedOptions.precision);
560
+ var included = value >= params.lowerValue && value <= params.upperValue;
609
561
  return params.exclude ? !included : included;
610
562
  };
611
563
  },