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.
- package/a11y/a11y.js +2 -2
- package/a11y/a11y.js.flow +3 -3
- package/button/styled-components.js +47 -18
- package/button/styled-components.js.flow +25 -5
- package/combobox/combobox.js +6 -3
- package/combobox/combobox.js.flow +4 -2
- package/combobox/types.js.flow +2 -0
- package/data-table/column-categorical.js +1 -1
- package/data-table/column-categorical.js.flow +2 -2
- package/data-table/column-numerical.js +307 -355
- package/data-table/column-numerical.js.flow +273 -287
- package/data-table/constants.js +17 -11
- package/data-table/constants.js.flow +11 -8
- package/data-table/data-table.js +53 -50
- package/data-table/data-table.js.flow +18 -13
- package/data-table/filter-shell.js +27 -4
- package/data-table/filter-shell.js.flow +33 -9
- package/data-table/locale.js +4 -2
- package/data-table/locale.js.flow +6 -2
- package/data-table/measure-column-widths.js +83 -121
- package/data-table/measure-column-widths.js.flow +87 -109
- package/datepicker/styled-components.js +1 -1
- package/datepicker/styled-components.js.flow +4 -1
- package/drawer/drawer.js +3 -1
- package/drawer/drawer.js.flow +7 -1
- package/es/a11y/a11y.js +2 -2
- package/es/button/styled-components.js +32 -2
- package/es/combobox/combobox.js +6 -3
- package/es/data-table/column-categorical.js +2 -2
- package/es/data-table/column-numerical.js +245 -317
- package/es/data-table/constants.js +12 -8
- package/es/data-table/data-table.js +18 -16
- package/es/data-table/filter-shell.js +26 -4
- package/es/data-table/locale.js +4 -2
- package/es/data-table/measure-column-widths.js +75 -86
- package/es/datepicker/styled-components.js +1 -1
- package/es/drawer/drawer.js +3 -1
- package/es/index.js +1 -1
- package/es/map-marker/badge-enhancer.js +61 -0
- package/es/map-marker/constants.js +146 -2
- package/es/map-marker/drag-shadow.js +32 -0
- package/es/map-marker/fixed-marker.js +54 -48
- package/es/map-marker/floating-marker.js +21 -12
- package/es/map-marker/index.js +1 -1
- package/es/map-marker/label-enhancer.js +39 -0
- package/es/map-marker/needle.js +26 -0
- package/es/map-marker/pin-head.js +42 -40
- package/es/map-marker/styled-components.js +177 -32
- package/es/map-marker/types.js +1 -1
- package/es/menu/maybe-child-menu.js +0 -2
- package/es/menu/nested-menus.js +49 -3
- package/es/menu/stateful-container.js +13 -12
- package/es/modal/modal.js +3 -1
- package/es/popover/popover.js +3 -1
- package/es/progress-bar/index.js +1 -1
- package/es/progress-bar/progressbar.js +25 -10
- package/es/progress-bar/styled-components.js +9 -5
- package/es/select/select-component.js +2 -10
- package/es/spinner/styled-components.js +34 -16
- package/es/table/filter.js +3 -1
- package/es/themes/dark-theme/color-component-tokens.js +4 -0
- package/es/themes/light-theme/color-component-tokens.js +4 -0
- package/es/timezonepicker/timezone-picker.js +53 -36
- package/es/timezonepicker/tzdata.js +2 -0
- package/es/timezonepicker/update-tzdata.js +69 -0
- package/esm/a11y/a11y.js +3 -3
- package/esm/button/styled-components.js +47 -18
- package/esm/combobox/combobox.js +6 -3
- package/esm/data-table/column-categorical.js +2 -2
- package/esm/data-table/column-numerical.js +304 -353
- package/esm/data-table/constants.js +12 -8
- package/esm/data-table/data-table.js +53 -50
- package/esm/data-table/filter-shell.js +26 -4
- package/esm/data-table/locale.js +4 -2
- package/esm/data-table/measure-column-widths.js +83 -121
- package/esm/datepicker/styled-components.js +1 -1
- package/esm/drawer/drawer.js +3 -1
- package/esm/index.js +1 -1
- package/esm/map-marker/badge-enhancer.js +79 -0
- package/esm/map-marker/constants.js +94 -4
- package/esm/map-marker/drag-shadow.js +53 -0
- package/esm/map-marker/fixed-marker.js +84 -80
- package/esm/map-marker/floating-marker.js +22 -13
- package/esm/map-marker/index.js +1 -1
- package/esm/map-marker/label-enhancer.js +60 -0
- package/esm/map-marker/needle.js +43 -0
- package/esm/map-marker/pin-head.js +77 -66
- package/esm/map-marker/styled-components.js +182 -51
- package/esm/map-marker/types.js +1 -1
- package/esm/menu/maybe-child-menu.js +0 -2
- package/esm/menu/nested-menus.js +66 -5
- package/esm/menu/stateful-container.js +15 -13
- package/esm/modal/modal.js +3 -1
- package/esm/popover/popover.js +3 -1
- package/esm/progress-bar/index.js +1 -1
- package/esm/progress-bar/progressbar.js +32 -10
- package/esm/progress-bar/styled-components.js +9 -4
- package/esm/select/select-component.js +2 -11
- package/esm/spinner/styled-components.js +35 -16
- package/esm/table/filter.js +3 -1
- package/esm/themes/dark-theme/color-component-tokens.js +4 -0
- package/esm/themes/light-theme/color-component-tokens.js +4 -0
- package/esm/timezonepicker/timezone-picker.js +64 -36
- package/esm/timezonepicker/tzdata.js +2 -0
- package/esm/timezonepicker/update-tzdata.js +160 -0
- package/index.js +6 -0
- package/index.js.flow +1 -1
- package/map-marker/badge-enhancer.js +90 -0
- package/map-marker/badge-enhancer.js.flow +86 -0
- package/map-marker/constants.js +103 -5
- package/map-marker/constants.js.flow +152 -0
- package/map-marker/drag-shadow.js +64 -0
- package/map-marker/drag-shadow.js.flow +52 -0
- package/map-marker/fixed-marker.js +84 -78
- package/map-marker/fixed-marker.js.flow +78 -66
- package/map-marker/floating-marker.js +22 -13
- package/map-marker/floating-marker.js.flow +30 -17
- package/map-marker/index.d.ts +125 -24
- package/map-marker/index.js +18 -0
- package/map-marker/index.js.flow +3 -0
- package/map-marker/label-enhancer.js +71 -0
- package/map-marker/label-enhancer.js.flow +63 -0
- package/map-marker/needle.js +54 -0
- package/map-marker/needle.js.flow +29 -0
- package/map-marker/pin-head.js +80 -69
- package/map-marker/pin-head.js.flow +122 -84
- package/map-marker/styled-components.js +200 -62
- package/map-marker/styled-components.js.flow +172 -22
- package/map-marker/types.js.flow +69 -20
- package/menu/index.d.ts +9 -4
- package/menu/maybe-child-menu.js +0 -2
- package/menu/maybe-child-menu.js.flow +0 -2
- package/menu/nested-menus.js +66 -5
- package/menu/nested-menus.js.flow +50 -5
- package/menu/stateful-container.js +15 -13
- package/menu/stateful-container.js.flow +19 -13
- package/menu/types.js.flow +7 -1
- package/modal/modal.js +3 -1
- package/modal/modal.js.flow +2 -0
- package/package.json +5 -4
- package/popover/popover.js +3 -1
- package/popover/popover.js.flow +2 -0
- package/progress-bar/index.d.ts +2 -0
- package/progress-bar/index.js +6 -0
- package/progress-bar/index.js.flow +1 -0
- package/progress-bar/progressbar.js +32 -10
- package/progress-bar/progressbar.js.flow +35 -9
- package/progress-bar/styled-components.js +9 -4
- package/progress-bar/styled-components.js.flow +15 -4
- package/progress-bar/types.js.flow +12 -2
- package/select/select-component.js +2 -11
- package/select/select-component.js.flow +5 -7
- package/spinner/styled-components.js +35 -16
- package/spinner/styled-components.js.flow +37 -19
- package/spinner/types.js.flow +10 -0
- package/styles/index.js.flow +1 -1
- package/table/filter.js +3 -1
- package/table/filter.js.flow +5 -1
- package/themes/dark-theme/color-component-tokens.js +4 -0
- package/themes/dark-theme/color-component-tokens.js.flow +4 -0
- package/themes/light-theme/color-component-tokens.js +4 -0
- package/themes/light-theme/color-component-tokens.js.flow +4 -0
- package/themes/types.js.flow +4 -0
- package/timezonepicker/timezone-picker.js +69 -41
- package/timezonepicker/timezone-picker.js.flow +52 -46
- package/timezonepicker/types.js.flow +1 -1
- package/timezonepicker/tzdata.js +10 -0
- package/timezonepicker/tzdata.js.flow +347 -0
- package/timezonepicker/update-tzdata.js +164 -0
- package/timezonepicker/update-tzdata.js.flow +70 -0
|
@@ -13,7 +13,7 @@ import { Checkbox, StyledLabel } from '../checkbox/index.js';
|
|
|
13
13
|
import Search from '../icon/search.js';
|
|
14
14
|
import { Input, SIZE as INPUT_SIZE } from '../input/index.js';
|
|
15
15
|
import { useStyletron, withStyle } from '../styles/index.js';
|
|
16
|
-
import {
|
|
16
|
+
import { LabelSmall } from '../typography/index.js';
|
|
17
17
|
import Column from './column.js';
|
|
18
18
|
import { COLUMNS } from './constants.js';
|
|
19
19
|
import { LocaleContext } from '../locale/index.js';
|
|
@@ -139,7 +139,7 @@ export function CategoricalFilter(props) {
|
|
|
139
139
|
overflowY: 'auto',
|
|
140
140
|
marginTop: theme.sizing.scale600
|
|
141
141
|
})
|
|
142
|
-
}, !filteredCategories.length && /*#__PURE__*/React.createElement(
|
|
142
|
+
}, !filteredCategories.length && /*#__PURE__*/React.createElement(LabelSmall, null, locale.datatable.categoricalFilterEmpty), Boolean(filteredCategories.length) && filteredCategories.map((category, i) => /*#__PURE__*/React.createElement("div", {
|
|
143
143
|
className: checkboxStyles,
|
|
144
144
|
key: i
|
|
145
145
|
}, /*#__PURE__*/React.createElement(Checkbox, {
|
|
@@ -11,11 +11,12 @@ import { Button, SIZE } from '../button/index.js';
|
|
|
11
11
|
import { ButtonGroup, MODE } from '../button-group/index.js';
|
|
12
12
|
import { Input, SIZE as INPUT_SIZE } from '../input/index.js';
|
|
13
13
|
import { useStyletron } from '../styles/index.js';
|
|
14
|
-
import { Paragraph4 } from '../typography/index.js';
|
|
15
14
|
import Column from './column.js';
|
|
16
|
-
import { COLUMNS, NUMERICAL_FORMATS,
|
|
15
|
+
import { COLUMNS, NUMERICAL_FORMATS, MAX_BIN_COUNT, HISTOGRAM_SIZE } from './constants.js';
|
|
17
16
|
import FilterShell from './filter-shell.js';
|
|
18
17
|
import { LocaleContext } from '../locale/index.js';
|
|
18
|
+
import { bin, max as maxFunc, extent, scaleLinear, median, bisector } from 'd3';
|
|
19
|
+
import { Slider } from '../slider/index.js';
|
|
19
20
|
|
|
20
21
|
function roundToFixed(value, precision) {
|
|
21
22
|
const k = Math.pow(10, precision);
|
|
@@ -62,250 +63,170 @@ function validateInput(input) {
|
|
|
62
63
|
return Boolean(parseFloat(input)) || input === '' || input === '-';
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
66
|
+
const bisect = bisector(d => d.x0);
|
|
67
|
+
const Histogram = /*#__PURE__*/React.memo(function Histogram({
|
|
68
|
+
data,
|
|
69
|
+
lower,
|
|
70
|
+
upper,
|
|
71
|
+
isRange,
|
|
72
|
+
exclude,
|
|
73
|
+
precision
|
|
74
|
+
}) {
|
|
75
|
+
const [css, theme] = useStyletron();
|
|
76
|
+
const {
|
|
77
|
+
bins,
|
|
78
|
+
xScale,
|
|
79
|
+
yScale
|
|
80
|
+
} = React.useMemo(() => {
|
|
81
|
+
const bins = bin().thresholds(Math.min(data.length, MAX_BIN_COUNT))(data);
|
|
82
|
+
const xScale = scaleLinear().domain([bins[0].x0, bins[bins.length - 1].x1]).range([0, HISTOGRAM_SIZE.width]).clamp(true);
|
|
83
|
+
const yScale = scaleLinear().domain([0, maxFunc(bins, d => d.length)]).nice().range([HISTOGRAM_SIZE.height, 0]);
|
|
84
|
+
return {
|
|
85
|
+
bins,
|
|
86
|
+
xScale,
|
|
87
|
+
yScale
|
|
88
|
+
};
|
|
89
|
+
}, [data]); // We need to find the index of bar which is nearest to the given single value
|
|
90
|
+
|
|
91
|
+
const singleIndexNearest = React.useMemo(() => {
|
|
92
|
+
if (isRange) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return bisect.center(bins, lower);
|
|
97
|
+
}, [isRange, data, lower, upper]);
|
|
98
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
99
|
+
className: css({
|
|
100
|
+
display: 'flex',
|
|
101
|
+
marginTop: theme.sizing.scale600,
|
|
102
|
+
marginLeft: theme.sizing.scale200,
|
|
103
|
+
marginRight: 0,
|
|
104
|
+
marginBottom: theme.sizing.scale400,
|
|
105
|
+
justifyContent: 'space-between',
|
|
106
|
+
overflow: 'visible'
|
|
107
|
+
})
|
|
108
|
+
}, /*#__PURE__*/React.createElement("svg", HISTOGRAM_SIZE, bins.map((d, index) => {
|
|
109
|
+
const x = xScale(d.x0) + 1;
|
|
110
|
+
const y = yScale(d.length);
|
|
111
|
+
const width = Math.max(0, xScale(d.x1) - xScale(d.x0) - 1);
|
|
112
|
+
const height = yScale(0) - yScale(d.length);
|
|
113
|
+
let included;
|
|
114
|
+
|
|
115
|
+
if (singleIndexNearest != null) {
|
|
116
|
+
included = index === singleIndexNearest;
|
|
77
117
|
} else {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
exclude: filterParams.exclude,
|
|
83
|
-
comparatorIndex: 0,
|
|
84
|
-
operatorIndex: 0,
|
|
85
|
-
left: '',
|
|
86
|
-
right: comparison.value.toString()
|
|
87
|
-
};
|
|
88
|
-
} else if (comparison.operation === NUMERICAL_OPERATIONS.GT) {
|
|
89
|
-
return {
|
|
90
|
-
exclude: filterParams.exclude,
|
|
91
|
-
comparatorIndex: 0,
|
|
92
|
-
operatorIndex: 1,
|
|
93
|
-
left: comparison.value.toString(),
|
|
94
|
-
right: ''
|
|
95
|
-
};
|
|
96
|
-
} else if (comparison.operation === NUMERICAL_OPERATIONS.LTE) {
|
|
97
|
-
return {
|
|
98
|
-
exclude: filterParams.exclude,
|
|
99
|
-
comparatorIndex: 0,
|
|
100
|
-
operatorIndex: 2,
|
|
101
|
-
left: '',
|
|
102
|
-
right: comparison.value.toString()
|
|
103
|
-
};
|
|
104
|
-
} else if (comparison.operation === NUMERICAL_OPERATIONS.GTE) {
|
|
105
|
-
return {
|
|
106
|
-
exclude: filterParams.exclude,
|
|
107
|
-
comparatorIndex: 0,
|
|
108
|
-
operatorIndex: 3,
|
|
109
|
-
left: comparison.value.toString(),
|
|
110
|
-
right: ''
|
|
111
|
-
};
|
|
112
|
-
} else if (comparison.operation === NUMERICAL_OPERATIONS.EQ) {
|
|
113
|
-
return {
|
|
114
|
-
exclude: filterParams.exclude,
|
|
115
|
-
comparatorIndex: 1,
|
|
116
|
-
operatorIndex: 0,
|
|
117
|
-
left: comparison.value.toString(),
|
|
118
|
-
right: ''
|
|
119
|
-
};
|
|
120
|
-
}
|
|
118
|
+
const withinLower = d.x1 > lower;
|
|
119
|
+
const withinUpper = d.x0 <= upper;
|
|
120
|
+
included = withinLower && withinUpper;
|
|
121
121
|
}
|
|
122
|
-
}
|
|
123
122
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
123
|
+
if (exclude) {
|
|
124
|
+
included = !included;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return /*#__PURE__*/React.createElement("rect", {
|
|
128
|
+
key: `bar-${index}`,
|
|
129
|
+
fill: included ? theme.colors.primary : theme.colors.mono400,
|
|
130
|
+
x: x,
|
|
131
|
+
y: y,
|
|
132
|
+
width: width,
|
|
133
|
+
height: height
|
|
134
|
+
});
|
|
135
|
+
})));
|
|
136
|
+
});
|
|
132
137
|
|
|
133
138
|
function NumericalFilter(props) {
|
|
134
139
|
const [css, theme] = useStyletron();
|
|
135
140
|
const locale = React.useContext(LocaleContext);
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
141
|
+
const precision = props.options.precision; // The state handling of this component could be refactored and cleaned up if we used useReducer.
|
|
142
|
+
|
|
143
|
+
const initialState = React.useMemo(() => {
|
|
144
|
+
return props.filterParams || {
|
|
145
|
+
exclude: false,
|
|
146
|
+
excludeKind: 'range',
|
|
147
|
+
comparatorIndex: 0,
|
|
148
|
+
lowerValue: null,
|
|
149
|
+
upperValue: null
|
|
150
|
+
};
|
|
151
|
+
}, [props.filterParams]);
|
|
152
|
+
const [exclude, setExclude] = React.useState(initialState.exclude); // the api of our ButtonGroup forces these numerical indexes...
|
|
153
|
+
// TODO look into allowing semantic names, similar to the radio component. Tricky part would be backwards compat
|
|
154
|
+
|
|
155
|
+
const [comparatorIndex, setComparatorIndex] = React.useState(() => {
|
|
156
|
+
switch (initialState.excludeKind) {
|
|
157
|
+
case 'value':
|
|
158
|
+
return 1;
|
|
159
|
+
|
|
160
|
+
case 'range':
|
|
161
|
+
default:
|
|
162
|
+
// fallthrough
|
|
163
|
+
return 0;
|
|
148
164
|
}
|
|
165
|
+
}); // We use the d3 function to get the extent as it's a little more robust to null, -Infinity, etc.
|
|
149
166
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const [leftDisabled, rightDisabled] = React.useMemo(() => {
|
|
155
|
-
if (!isRange) return [false, false];
|
|
167
|
+
const [min, max] = React.useMemo(() => extent(props.data), [props.data]);
|
|
168
|
+
const [lv, setLower] = React.useState(() => roundToFixed(initialState.lowerValue || min, precision));
|
|
169
|
+
const [uv, setUpper] = React.useState(() => roundToFixed(initialState.upperValue || max, precision)); // We keep a separate value for the single select, to give a user the ability to toggle between
|
|
170
|
+
// the range and single values without losing their previous input.
|
|
156
171
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
172
|
+
const [sv, setSingle] = React.useState(() => roundToFixed(initialState.lowerValue || median(props.data), precision)); // This is the only conditional which we want to use to determine
|
|
173
|
+
// if we are in range or single value mode.
|
|
174
|
+
// Don't derive it via something else, e.g. lowerValue === upperValue, etc.
|
|
160
175
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
176
|
+
const isRange = comparatorIndex === 0;
|
|
177
|
+
const excludeKind = isRange ? 'range' : 'value'; // while the user is inputting values, we take their input at face value,
|
|
178
|
+
// if we don't do this, a user can't input partial numbers, e.g. "-", or "3."
|
|
164
179
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
180
|
+
const [focused, setFocus] = React.useState(false);
|
|
181
|
+
const [inputValueLower, inputValueUpper] = React.useMemo(() => {
|
|
182
|
+
if (focused) {
|
|
183
|
+
return [isRange ? lv : sv, uv];
|
|
184
|
+
} // once the user is done inputting.
|
|
185
|
+
// we validate then format to the given precision
|
|
168
186
|
|
|
169
|
-
default:
|
|
170
|
-
return [true, true];
|
|
171
|
-
}
|
|
172
|
-
}, [operatorIndex, isRange]);
|
|
173
|
-
const leftInputRef = React.useRef(null);
|
|
174
|
-
const rightInputRef = React.useRef(null);
|
|
175
|
-
React.useEffect(() => {
|
|
176
|
-
if (!leftDisabled && leftInputRef.current) {
|
|
177
|
-
leftInputRef.current.focus({
|
|
178
|
-
preventScroll: true
|
|
179
|
-
});
|
|
180
|
-
} else if (!rightDisabled && rightInputRef.current) {
|
|
181
|
-
rightInputRef.current.focus({
|
|
182
|
-
preventScroll: true
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
}, [leftDisabled, rightDisabled, comparatorIndex]);
|
|
186
|
-
React.useEffect(() => {
|
|
187
|
-
switch (operatorIndex) {
|
|
188
|
-
case 4:
|
|
189
|
-
default:
|
|
190
|
-
break;
|
|
191
187
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
188
|
+
let l = isRange ? lv : sv;
|
|
189
|
+
l = validateInput(l) ? l : min;
|
|
190
|
+
let h = validateInput(uv) ? uv : max;
|
|
191
|
+
return [roundToFixed(l, precision), roundToFixed(h, precision)];
|
|
192
|
+
}, [isRange, focused, sv, lv, uv, precision]); // We bound the values within our min and max even if a user enters a huge number
|
|
193
|
+
|
|
194
|
+
let 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
|
|
195
|
+
|
|
196
|
+
if (isRange && sliderValue[0] > sliderValue[1]) {
|
|
197
|
+
sliderValue = [sliderValue[1], sliderValue[0]];
|
|
198
|
+
}
|
|
196
199
|
|
|
197
|
-
case 0:
|
|
198
|
-
case 2:
|
|
199
|
-
setLeft(min.toString());
|
|
200
|
-
break;
|
|
201
|
-
}
|
|
202
|
-
}, [operatorIndex]);
|
|
203
200
|
return /*#__PURE__*/React.createElement(FilterShell, {
|
|
204
201
|
exclude: exclude,
|
|
205
202
|
onExcludeChange: () => setExclude(!exclude),
|
|
203
|
+
excludeKind: excludeKind,
|
|
206
204
|
onApply: () => {
|
|
207
205
|
if (isRange) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}],
|
|
218
|
-
description: `< ${value}`,
|
|
219
|
-
exclude
|
|
220
|
-
});
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
case 1:
|
|
225
|
-
{
|
|
226
|
-
const value = parseFloat(left);
|
|
227
|
-
const operation = NUMERICAL_OPERATIONS.GT;
|
|
228
|
-
props.setFilter({
|
|
229
|
-
comparisons: [{
|
|
230
|
-
value,
|
|
231
|
-
operation
|
|
232
|
-
}],
|
|
233
|
-
description: `> ${value}`,
|
|
234
|
-
exclude
|
|
235
|
-
});
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
case 2:
|
|
240
|
-
{
|
|
241
|
-
const value = parseFloat(right);
|
|
242
|
-
const operation = NUMERICAL_OPERATIONS.LTE;
|
|
243
|
-
props.setFilter({
|
|
244
|
-
comparisons: [{
|
|
245
|
-
value,
|
|
246
|
-
operation
|
|
247
|
-
}],
|
|
248
|
-
description: `≤ ${value}`,
|
|
249
|
-
exclude
|
|
250
|
-
});
|
|
251
|
-
break;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
case 3:
|
|
255
|
-
{
|
|
256
|
-
const value = parseFloat(left);
|
|
257
|
-
const operation = NUMERICAL_OPERATIONS.GTE;
|
|
258
|
-
props.setFilter({
|
|
259
|
-
comparisons: [{
|
|
260
|
-
value,
|
|
261
|
-
operation
|
|
262
|
-
}],
|
|
263
|
-
description: `≥ ${value}`,
|
|
264
|
-
exclude
|
|
265
|
-
});
|
|
266
|
-
break;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
case 4:
|
|
270
|
-
{
|
|
271
|
-
// 'between' case is interesting since if we want less than 10 plus greater than 5
|
|
272
|
-
// comparators, the filter will include _all_ numbers.
|
|
273
|
-
const leftValue = parseFloat(left);
|
|
274
|
-
const rightValue = parseFloat(right);
|
|
275
|
-
props.setFilter({
|
|
276
|
-
comparisons: [{
|
|
277
|
-
value: leftValue,
|
|
278
|
-
operation: NUMERICAL_OPERATIONS.LT
|
|
279
|
-
}, {
|
|
280
|
-
value: rightValue,
|
|
281
|
-
operation: NUMERICAL_OPERATIONS.GT
|
|
282
|
-
}],
|
|
283
|
-
description: `≥ ${leftValue} & ≤ ${rightValue}`,
|
|
284
|
-
exclude: !exclude
|
|
285
|
-
});
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
default:
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
206
|
+
const lowerValue = parseFloat(inputValueLower);
|
|
207
|
+
const upperValue = parseFloat(inputValueUpper);
|
|
208
|
+
props.setFilter({
|
|
209
|
+
description: `≥ ${lowerValue} and ≤ ${upperValue}`,
|
|
210
|
+
exclude: exclude,
|
|
211
|
+
lowerValue,
|
|
212
|
+
upperValue,
|
|
213
|
+
excludeKind
|
|
214
|
+
});
|
|
292
215
|
} else {
|
|
293
|
-
const value = parseFloat(
|
|
294
|
-
const operation = NUMERICAL_OPERATIONS.EQ;
|
|
216
|
+
const value = parseFloat(inputValueLower);
|
|
295
217
|
props.setFilter({
|
|
296
|
-
comparisons: [{
|
|
297
|
-
value,
|
|
298
|
-
operation
|
|
299
|
-
}],
|
|
300
218
|
description: `= ${value}`,
|
|
301
|
-
exclude
|
|
219
|
+
exclude: exclude,
|
|
220
|
+
lowerValue: inputValueLower,
|
|
221
|
+
upperValue: inputValueLower,
|
|
222
|
+
excludeKind
|
|
302
223
|
});
|
|
303
224
|
}
|
|
304
225
|
|
|
305
226
|
props.close();
|
|
306
227
|
}
|
|
307
228
|
}, /*#__PURE__*/React.createElement(ButtonGroup, {
|
|
308
|
-
size: SIZE.
|
|
229
|
+
size: SIZE.mini,
|
|
309
230
|
mode: MODE.radio,
|
|
310
231
|
selected: comparatorIndex,
|
|
311
232
|
onClick: (_, index) => setComparatorIndex(index),
|
|
@@ -326,7 +247,8 @@ function NumericalFilter(props) {
|
|
|
326
247
|
width: '100%'
|
|
327
248
|
}
|
|
328
249
|
}
|
|
329
|
-
}
|
|
250
|
+
},
|
|
251
|
+
"aria-label": locale.datatable.numericalFilterRange
|
|
330
252
|
}, locale.datatable.numericalFilterRange), /*#__PURE__*/React.createElement(Button, {
|
|
331
253
|
type: "button",
|
|
332
254
|
overrides: {
|
|
@@ -335,112 +257,140 @@ function NumericalFilter(props) {
|
|
|
335
257
|
width: '100%'
|
|
336
258
|
}
|
|
337
259
|
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
260
|
+
},
|
|
261
|
+
"aria-label": locale.datatable.numericalFilterSingleValue
|
|
262
|
+
}, locale.datatable.numericalFilterSingleValue)), /*#__PURE__*/React.createElement(Histogram, {
|
|
263
|
+
data: props.data,
|
|
264
|
+
lower: inputValueLower,
|
|
265
|
+
upper: inputValueUpper,
|
|
266
|
+
isRange: isRange,
|
|
267
|
+
exclude: exclude,
|
|
268
|
+
precision: props.options.precision
|
|
269
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
270
|
+
className: css({
|
|
271
|
+
display: 'flex',
|
|
272
|
+
justifyContent: 'space-between'
|
|
273
|
+
})
|
|
274
|
+
}, /*#__PURE__*/React.createElement(Slider // The slider throws errors when switching between single and two values
|
|
275
|
+
// when it tries to read getThumbDistance on a thumb which is not there anymore
|
|
276
|
+
// if we create a new instance these errors are prevented.
|
|
277
|
+
, {
|
|
278
|
+
key: isRange.toString(),
|
|
279
|
+
min: min,
|
|
280
|
+
max: max,
|
|
281
|
+
value: sliderValue,
|
|
282
|
+
onChange: ({
|
|
283
|
+
value
|
|
284
|
+
}) => {
|
|
285
|
+
if (!value) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (isRange) {
|
|
290
|
+
const [lowerValue, upperValue] = value;
|
|
291
|
+
setLower(lowerValue);
|
|
292
|
+
setUpper(upperValue);
|
|
293
|
+
} else {
|
|
294
|
+
const [singleValue] = value;
|
|
295
|
+
setSingle(singleValue);
|
|
296
|
+
}
|
|
297
|
+
},
|
|
344
298
|
overrides: {
|
|
299
|
+
InnerThumb: function InnerThumb({
|
|
300
|
+
$value,
|
|
301
|
+
$thumbIndex
|
|
302
|
+
}) {
|
|
303
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, $value[$thumbIndex]);
|
|
304
|
+
},
|
|
305
|
+
TickBar: ({
|
|
306
|
+
$min,
|
|
307
|
+
$max
|
|
308
|
+
}) => null,
|
|
309
|
+
// we don't want the ticks
|
|
310
|
+
ThumbValue: () => null,
|
|
345
311
|
Root: {
|
|
312
|
+
style: () => ({
|
|
313
|
+
// Aligns the center of the slider handles with the histogram bars
|
|
314
|
+
width: 'calc(100% + 14px)',
|
|
315
|
+
margin: '0 -7px'
|
|
316
|
+
})
|
|
317
|
+
},
|
|
318
|
+
InnerTrack: {
|
|
346
319
|
style: ({
|
|
347
320
|
$theme
|
|
348
|
-
}) =>
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
BaseButton: {
|
|
357
|
-
style: {
|
|
358
|
-
width: '100%'
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}, "<"), /*#__PURE__*/React.createElement(Button, {
|
|
363
|
-
type: "button",
|
|
364
|
-
overrides: {
|
|
365
|
-
BaseButton: {
|
|
366
|
-
style: {
|
|
367
|
-
width: '100%'
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}, ">"), /*#__PURE__*/React.createElement(Button, {
|
|
372
|
-
type: "button",
|
|
373
|
-
overrides: {
|
|
374
|
-
BaseButton: {
|
|
375
|
-
style: {
|
|
376
|
-
width: '100%'
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}, "\u2264"), /*#__PURE__*/React.createElement(Button, {
|
|
381
|
-
type: "button",
|
|
382
|
-
overrides: {
|
|
383
|
-
BaseButton: {
|
|
384
|
-
style: {
|
|
385
|
-
width: '100%'
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}, "\u2265"), /*#__PURE__*/React.createElement(Button, {
|
|
390
|
-
type: "button",
|
|
391
|
-
overrides: {
|
|
392
|
-
BaseButton: {
|
|
393
|
-
style: {
|
|
394
|
-
width: '100%'
|
|
321
|
+
}) => {
|
|
322
|
+
if (!isRange) {
|
|
323
|
+
return {
|
|
324
|
+
// For range selection we use the color as is, but when selecting the single value,
|
|
325
|
+
// we don't want the track standing out, so mute its color
|
|
326
|
+
background: theme.colors.mono400
|
|
327
|
+
};
|
|
328
|
+
}
|
|
395
329
|
}
|
|
330
|
+
},
|
|
331
|
+
Thumb: {
|
|
332
|
+
style: () => ({
|
|
333
|
+
// Slider handles are small enough to visually be centered within each histogram bar
|
|
334
|
+
height: '18px',
|
|
335
|
+
width: '18px',
|
|
336
|
+
fontSize: '0px'
|
|
337
|
+
})
|
|
396
338
|
}
|
|
397
339
|
}
|
|
398
|
-
}
|
|
399
|
-
className: css({
|
|
400
|
-
display: 'flex',
|
|
401
|
-
justifyContent: 'space-between',
|
|
402
|
-
marginLeft: theme.sizing.scale300,
|
|
403
|
-
marginRight: theme.sizing.scale300
|
|
404
|
-
})
|
|
405
|
-
}, /*#__PURE__*/React.createElement(Paragraph4, null, format(min, props.options)), ' ', /*#__PURE__*/React.createElement(Paragraph4, null, format(max, props.options))), /*#__PURE__*/React.createElement("div", {
|
|
340
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
406
341
|
className: css({
|
|
407
342
|
display: 'flex',
|
|
343
|
+
marginTop: theme.sizing.scale400,
|
|
344
|
+
// This % gap is visually appealing given the filter box width
|
|
345
|
+
gap: '30%',
|
|
408
346
|
justifyContent: 'space-between'
|
|
409
347
|
})
|
|
410
348
|
}, /*#__PURE__*/React.createElement(Input, {
|
|
411
|
-
|
|
349
|
+
min: min,
|
|
350
|
+
max: max,
|
|
351
|
+
size: INPUT_SIZE.mini,
|
|
412
352
|
overrides: {
|
|
413
353
|
Root: {
|
|
414
354
|
style: {
|
|
415
|
-
width:
|
|
355
|
+
width: '100%'
|
|
416
356
|
}
|
|
417
357
|
}
|
|
418
358
|
},
|
|
419
|
-
|
|
420
|
-
inputRef: leftInputRef,
|
|
421
|
-
value: left,
|
|
359
|
+
value: inputValueLower,
|
|
422
360
|
onChange: event => {
|
|
423
361
|
if (validateInput(event.target.value)) {
|
|
424
|
-
|
|
362
|
+
isRange ? // $FlowFixMe - we know it is a number by now
|
|
363
|
+
setLower(event.target.value) : // $FlowFixMe - we know it is a number by now
|
|
364
|
+
setSingle(event.target.value);
|
|
425
365
|
}
|
|
426
|
-
}
|
|
366
|
+
},
|
|
367
|
+
onFocus: () => setFocus(true),
|
|
368
|
+
onBlur: () => setFocus(false)
|
|
427
369
|
}), isRange && /*#__PURE__*/React.createElement(Input, {
|
|
428
|
-
|
|
370
|
+
min: min,
|
|
371
|
+
max: max,
|
|
372
|
+
size: INPUT_SIZE.mini,
|
|
429
373
|
overrides: {
|
|
374
|
+
Input: {
|
|
375
|
+
style: {
|
|
376
|
+
textAlign: 'right'
|
|
377
|
+
}
|
|
378
|
+
},
|
|
430
379
|
Root: {
|
|
431
380
|
style: {
|
|
432
|
-
width: '
|
|
381
|
+
width: '100%'
|
|
433
382
|
}
|
|
434
383
|
}
|
|
435
384
|
},
|
|
436
|
-
|
|
437
|
-
inputRef: rightInputRef,
|
|
438
|
-
value: right,
|
|
385
|
+
value: inputValueUpper,
|
|
439
386
|
onChange: event => {
|
|
440
387
|
if (validateInput(event.target.value)) {
|
|
441
|
-
|
|
388
|
+
// $FlowFixMe - we know it is a number by now
|
|
389
|
+
setUpper(event.target.value);
|
|
442
390
|
}
|
|
443
|
-
}
|
|
391
|
+
},
|
|
392
|
+
onFocus: () => setFocus(true),
|
|
393
|
+
onBlur: () => setFocus(false)
|
|
444
394
|
})));
|
|
445
395
|
}
|
|
446
396
|
|
|
@@ -485,30 +435,8 @@ function NumericalColumn(options) {
|
|
|
485
435
|
kind: COLUMNS.NUMERICAL,
|
|
486
436
|
buildFilter: function (params) {
|
|
487
437
|
return function (data) {
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
const right = roundToFixed(c.value, normalizedOptions.precision);
|
|
491
|
-
|
|
492
|
-
switch (c.operation) {
|
|
493
|
-
case NUMERICAL_OPERATIONS.EQ:
|
|
494
|
-
return left === right;
|
|
495
|
-
|
|
496
|
-
case NUMERICAL_OPERATIONS.GT:
|
|
497
|
-
return left > right;
|
|
498
|
-
|
|
499
|
-
case NUMERICAL_OPERATIONS.GTE:
|
|
500
|
-
return left >= right;
|
|
501
|
-
|
|
502
|
-
case NUMERICAL_OPERATIONS.LT:
|
|
503
|
-
return left < right;
|
|
504
|
-
|
|
505
|
-
case NUMERICAL_OPERATIONS.LTE:
|
|
506
|
-
return left <= right;
|
|
507
|
-
|
|
508
|
-
default:
|
|
509
|
-
return true;
|
|
510
|
-
}
|
|
511
|
-
});
|
|
438
|
+
const value = roundToFixed(data, normalizedOptions.precision);
|
|
439
|
+
const included = value >= params.lowerValue && value <= params.upperValue;
|
|
512
440
|
return params.exclude ? !included : included;
|
|
513
441
|
};
|
|
514
442
|
},
|