1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | Object.defineProperty(exports, "__esModule", { value: true });
|
18 | exports.MultiSlider = void 0;
|
19 | var tslib_1 = require("tslib");
|
20 | var classnames_1 = tslib_1.__importDefault(require("classnames"));
|
21 | var React = tslib_1.__importStar(require("react"));
|
22 | var common_1 = require("../../common");
|
23 | var Errors = tslib_1.__importStar(require("../../common/errors"));
|
24 | var props_1 = require("../../common/props");
|
25 | var Utils = tslib_1.__importStar(require("../../common/utils"));
|
26 | var handle_1 = require("./handle");
|
27 | var handleProps_1 = require("./handleProps");
|
28 | var sliderUtils_1 = require("./sliderUtils");
|
29 |
|
30 |
|
31 |
|
32 |
|
33 | var MultiSliderHandle = function () { return null; };
|
34 | MultiSliderHandle.displayName = "".concat(props_1.DISPLAYNAME_PREFIX, ".MultiSliderHandle");
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 | var MultiSlider = (function (_super) {
|
41 | tslib_1.__extends(MultiSlider, _super);
|
42 | function MultiSlider() {
|
43 | var _this = _super !== null && _super.apply(this, arguments) || this;
|
44 | _this.state = {
|
45 | labelPrecision: getLabelPrecision(_this.props),
|
46 | tickSize: 0,
|
47 | tickSizeRatio: 0,
|
48 | };
|
49 | _this.handleElements = [];
|
50 | _this.trackElement = null;
|
51 | _this.addHandleRef = function (ref) {
|
52 | if (ref != null) {
|
53 | _this.handleElements.push(ref);
|
54 | }
|
55 | };
|
56 | _this.maybeHandleTrackClick = function (event) {
|
57 | if (_this.canHandleTrackEvent(event)) {
|
58 | var foundHandle = _this.nearestHandleForValue(_this.handleElements, function (handle) {
|
59 | return handle.mouseEventClientOffset(event);
|
60 | });
|
61 | if (foundHandle) {
|
62 | foundHandle.beginHandleMovement(event);
|
63 | }
|
64 | }
|
65 | };
|
66 | _this.maybeHandleTrackTouch = function (event) {
|
67 | if (_this.canHandleTrackEvent(event)) {
|
68 | var foundHandle = _this.nearestHandleForValue(_this.handleElements, function (handle) {
|
69 | return handle.touchEventClientOffset(event);
|
70 | });
|
71 | if (foundHandle) {
|
72 | foundHandle.beginHandleTouchMovement(event);
|
73 | }
|
74 | }
|
75 | };
|
76 | _this.canHandleTrackEvent = function (event) {
|
77 | var target = event.target;
|
78 |
|
79 | return !_this.props.disabled && target.closest(".".concat(common_1.Classes.SLIDER_HANDLE)) == null;
|
80 | };
|
81 | _this.getHandlerForIndex = function (index, callback) {
|
82 | return function (newValue) {
|
83 | callback === null || callback === void 0 ? void 0 : callback(_this.getNewHandleValues(newValue, index));
|
84 | };
|
85 | };
|
86 | _this.handleChange = function (newValues) {
|
87 | var _a, _b;
|
88 | var handleProps = getSortedInteractiveHandleProps(_this.props);
|
89 | var oldValues = handleProps.map(function (handle) { return handle.value; });
|
90 | if (!Utils.arraysEqual(newValues, oldValues)) {
|
91 | (_b = (_a = _this.props).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, newValues);
|
92 | handleProps.forEach(function (handle, index) {
|
93 | var _a;
|
94 | if (oldValues[index] !== newValues[index]) {
|
95 | (_a = handle.onChange) === null || _a === void 0 ? void 0 : _a.call(handle, newValues[index]);
|
96 | }
|
97 | });
|
98 | }
|
99 | };
|
100 | _this.handleRelease = function (newValues) {
|
101 | var _a, _b;
|
102 | var handleProps = getSortedInteractiveHandleProps(_this.props);
|
103 | (_b = (_a = _this.props).onRelease) === null || _b === void 0 ? void 0 : _b.call(_a, newValues);
|
104 | handleProps.forEach(function (handle, index) {
|
105 | var _a;
|
106 | (_a = handle.onRelease) === null || _a === void 0 ? void 0 : _a.call(handle, newValues[index]);
|
107 | });
|
108 | };
|
109 | return _this;
|
110 | }
|
111 | MultiSlider.getDerivedStateFromProps = function (props) {
|
112 | return { labelPrecision: MultiSlider.getLabelPrecision(props) };
|
113 | };
|
114 | MultiSlider.getLabelPrecision = function (_a) {
|
115 | var labelPrecision = _a.labelPrecision, stepSize = _a.stepSize;
|
116 |
|
117 | return labelPrecision == null ? Utils.countDecimalPlaces(stepSize) : labelPrecision;
|
118 | };
|
119 | MultiSlider.prototype.getSnapshotBeforeUpdate = function (prevProps) {
|
120 | var prevHandleProps = getSortedInteractiveHandleProps(prevProps);
|
121 | var newHandleProps = getSortedInteractiveHandleProps(this.props);
|
122 | if (newHandleProps.length !== prevHandleProps.length) {
|
123 |
|
124 | this.handleElements = [];
|
125 | }
|
126 | return null;
|
127 | };
|
128 | MultiSlider.prototype.render = function () {
|
129 | var _a;
|
130 | var _this = this;
|
131 | var classes = (0, classnames_1.default)(common_1.Classes.SLIDER, (_a = {},
|
132 | _a[common_1.Classes.DISABLED] = this.props.disabled,
|
133 | _a["".concat(common_1.Classes.SLIDER, "-unlabeled")] = this.props.labelRenderer === false,
|
134 | _a[common_1.Classes.VERTICAL] = this.props.vertical,
|
135 | _a), this.props.className);
|
136 | return (React.createElement("div", { className: classes, onMouseDown: this.maybeHandleTrackClick, onTouchStart: this.maybeHandleTrackTouch },
|
137 | React.createElement("div", { className: common_1.Classes.SLIDER_TRACK, ref: function (ref) { return (_this.trackElement = ref); } }, this.renderTracks()),
|
138 | React.createElement("div", { className: common_1.Classes.SLIDER_AXIS }, this.renderLabels()),
|
139 | this.renderHandles()));
|
140 | };
|
141 | MultiSlider.prototype.componentDidMount = function () {
|
142 | this.updateTickSize();
|
143 | };
|
144 | MultiSlider.prototype.componentDidUpdate = function (prevProps, prevState) {
|
145 | _super.prototype.componentDidUpdate.call(this, prevProps, prevState);
|
146 | this.updateTickSize();
|
147 | };
|
148 | MultiSlider.prototype.validateProps = function (props) {
|
149 | if (props.stepSize <= 0) {
|
150 | throw new Error(Errors.SLIDER_ZERO_STEP);
|
151 | }
|
152 | if (props.labelStepSize !== undefined && props.labelValues !== undefined) {
|
153 | throw new Error(Errors.MULTISLIDER_WARN_LABEL_STEP_SIZE_LABEL_VALUES_MUTEX);
|
154 | }
|
155 | if (props.labelStepSize !== undefined && props.labelStepSize <= 0) {
|
156 | throw new Error(Errors.SLIDER_ZERO_LABEL_STEP);
|
157 | }
|
158 | var anyInvalidChildren = false;
|
159 | React.Children.forEach(props.children, function (child) {
|
160 |
|
161 | if (child && !Utils.isElementOfType(child, MultiSlider.Handle)) {
|
162 | anyInvalidChildren = true;
|
163 | }
|
164 | });
|
165 | if (anyInvalidChildren) {
|
166 | throw new Error(Errors.MULTISLIDER_INVALID_CHILD);
|
167 | }
|
168 | };
|
169 | MultiSlider.prototype.formatLabel = function (value, isHandleTooltip) {
|
170 | if (isHandleTooltip === void 0) { isHandleTooltip = false; }
|
171 | var labelRenderer = this.props.labelRenderer;
|
172 | if (labelRenderer === false) {
|
173 | return undefined;
|
174 | }
|
175 | else if (Utils.isFunction(labelRenderer)) {
|
176 | return labelRenderer(value, { isHandleTooltip: isHandleTooltip });
|
177 | }
|
178 | else {
|
179 | return value.toFixed(this.state.labelPrecision);
|
180 | }
|
181 | };
|
182 | MultiSlider.prototype.renderLabels = function () {
|
183 | var _this = this;
|
184 | if (this.props.labelRenderer === false) {
|
185 | return null;
|
186 | }
|
187 | var values = this.getLabelValues();
|
188 | var _a = this.props, max = _a.max, min = _a.min;
|
189 | var labels = values.map(function (step, i) {
|
190 | var offsetPercentage = (0, sliderUtils_1.formatPercentage)((step - min) / (max - min));
|
191 | var style = _this.props.vertical ? { bottom: offsetPercentage } : { left: offsetPercentage };
|
192 | return (React.createElement("div", { className: common_1.Classes.SLIDER_LABEL, key: i, style: style }, _this.formatLabel(step)));
|
193 | });
|
194 | return labels;
|
195 | };
|
196 | MultiSlider.prototype.renderTracks = function () {
|
197 | var trackStops = getSortedHandleProps(this.props);
|
198 | trackStops.push({ value: this.props.max });
|
199 |
|
200 | var previous = { value: this.props.min };
|
201 | var handles = [];
|
202 | for (var index = 0; index < trackStops.length; index++) {
|
203 | var current = trackStops[index];
|
204 | handles.push(this.renderTrackFill(index, previous, current));
|
205 | previous = current;
|
206 | }
|
207 | return handles;
|
208 | };
|
209 | MultiSlider.prototype.renderTrackFill = function (index, start, end) {
|
210 |
|
211 | var _a = [this.getOffsetRatio(start.value), this.getOffsetRatio(end.value)].sort(function (left, right) { return left - right; }), startRatio = _a[0], endRatio = _a[1];
|
212 | var startOffset = (0, sliderUtils_1.formatPercentage)(startRatio);
|
213 | var endOffset = (0, sliderUtils_1.formatPercentage)(1 - endRatio);
|
214 | var orientationStyle = this.props.vertical
|
215 | ? { bottom: startOffset, top: endOffset, left: 0 }
|
216 | : { left: startOffset, right: endOffset, top: 0 };
|
217 | var style = tslib_1.__assign(tslib_1.__assign({}, orientationStyle), (start.trackStyleAfter || end.trackStyleBefore || {}));
|
218 | var classes = (0, classnames_1.default)(common_1.Classes.SLIDER_PROGRESS, common_1.Classes.intentClass(this.getTrackIntent(start, end)));
|
219 | return React.createElement("div", { key: "track-".concat(index), className: classes, style: style });
|
220 | };
|
221 | MultiSlider.prototype.renderHandles = function () {
|
222 | var _this = this;
|
223 | var _a = this.props, disabled = _a.disabled, max = _a.max, min = _a.min, stepSize = _a.stepSize, vertical = _a.vertical;
|
224 | var handleProps = getSortedInteractiveHandleProps(this.props);
|
225 | if (handleProps.length === 0) {
|
226 | return null;
|
227 | }
|
228 | return handleProps.map(function (_a, index) {
|
229 | var _b;
|
230 | var value = _a.value, type = _a.type, className = _a.className, htmlProps = _a.htmlProps;
|
231 | return (React.createElement(handle_1.Handle, { htmlProps: htmlProps, className: (0, classnames_1.default)((_b = {},
|
232 | _b[common_1.Classes.START] = type === handleProps_1.HandleType.START,
|
233 | _b[common_1.Classes.END] = type === handleProps_1.HandleType.END,
|
234 | _b), className), disabled: disabled, key: "".concat(index, "-").concat(handleProps.length), label: _this.formatLabel(value, true), max: max, min: min, onChange: _this.getHandlerForIndex(index, _this.handleChange), onRelease: _this.getHandlerForIndex(index, _this.handleRelease), ref: _this.addHandleRef, stepSize: stepSize, tickSize: _this.state.tickSize, tickSizeRatio: _this.state.tickSizeRatio, value: value, vertical: vertical }));
|
235 | });
|
236 | };
|
237 | MultiSlider.prototype.nearestHandleForValue = function (handles, getOffset) {
|
238 | return (0, sliderUtils_1.argMin)(handles, function (handle) {
|
239 | var offset = getOffset(handle);
|
240 | var offsetValue = handle.clientToValue(offset);
|
241 | var handleValue = handle.props.value;
|
242 | return Math.abs(offsetValue - handleValue);
|
243 | });
|
244 | };
|
245 | MultiSlider.prototype.getNewHandleValues = function (newValue, oldIndex) {
|
246 | var handleProps = getSortedInteractiveHandleProps(this.props);
|
247 | var oldValues = handleProps.map(function (handle) { return handle.value; });
|
248 | var newValues = oldValues.slice();
|
249 | newValues[oldIndex] = newValue;
|
250 | newValues.sort(function (left, right) { return left - right; });
|
251 | var newIndex = newValues.indexOf(newValue);
|
252 | var lockIndex = this.findFirstLockedHandleIndex(oldIndex, newIndex);
|
253 | if (lockIndex === -1) {
|
254 | (0, sliderUtils_1.fillValues)(newValues, oldIndex, newIndex, newValue);
|
255 | }
|
256 | else {
|
257 |
|
258 | var lockValue = oldValues[lockIndex];
|
259 | (0, sliderUtils_1.fillValues)(oldValues, oldIndex, lockIndex, lockValue);
|
260 | return oldValues;
|
261 | }
|
262 | return newValues;
|
263 | };
|
264 | MultiSlider.prototype.findFirstLockedHandleIndex = function (startIndex, endIndex) {
|
265 | var inc = startIndex < endIndex ? 1 : -1;
|
266 | var handleProps = getSortedInteractiveHandleProps(this.props);
|
267 | for (var index = startIndex + inc; index !== endIndex + inc; index += inc) {
|
268 | if (handleProps[index].interactionKind !== handleProps_1.HandleInteractionKind.PUSH) {
|
269 | return index;
|
270 | }
|
271 | }
|
272 | return -1;
|
273 | };
|
274 | MultiSlider.prototype.getLabelValues = function () {
|
275 | var _a = this.props, labelStepSize = _a.labelStepSize, labelValues = _a.labelValues, min = _a.min, max = _a.max;
|
276 | var values = [];
|
277 | if (labelValues !== undefined) {
|
278 | values = labelValues.slice();
|
279 | }
|
280 | else {
|
281 | for (var i = min; i < max || Utils.approxEqual(i, max); i += labelStepSize !== null && labelStepSize !== void 0 ? labelStepSize : 1) {
|
282 | values.push(i);
|
283 | }
|
284 | }
|
285 | return values;
|
286 | };
|
287 | MultiSlider.prototype.getOffsetRatio = function (value) {
|
288 | return Utils.clamp((value - this.props.min) * this.state.tickSizeRatio, 0, 1);
|
289 | };
|
290 | MultiSlider.prototype.getTrackIntent = function (start, end) {
|
291 | if (!this.props.showTrackFill) {
|
292 | return common_1.Intent.NONE;
|
293 | }
|
294 | if (start.intentAfter !== undefined) {
|
295 | return start.intentAfter;
|
296 | }
|
297 | else if (end !== undefined && end.intentBefore !== undefined) {
|
298 | return end.intentBefore;
|
299 | }
|
300 | return this.props.defaultTrackIntent;
|
301 | };
|
302 | MultiSlider.prototype.updateTickSize = function () {
|
303 | if (this.trackElement != null) {
|
304 | var trackSize = this.props.vertical ? this.trackElement.clientHeight : this.trackElement.clientWidth;
|
305 | var tickSizeRatio = 1 / (this.props.max - this.props.min);
|
306 | var tickSize = trackSize * tickSizeRatio;
|
307 | this.setState({ tickSize: tickSize, tickSizeRatio: tickSizeRatio });
|
308 | }
|
309 | };
|
310 | MultiSlider.defaultSliderProps = {
|
311 | disabled: false,
|
312 | max: 10,
|
313 | min: 0,
|
314 | showTrackFill: true,
|
315 | stepSize: 1,
|
316 | vertical: false,
|
317 | };
|
318 | MultiSlider.defaultProps = tslib_1.__assign(tslib_1.__assign({}, MultiSlider.defaultSliderProps), { defaultTrackIntent: common_1.Intent.NONE });
|
319 | MultiSlider.displayName = "".concat(props_1.DISPLAYNAME_PREFIX, ".MultiSlider");
|
320 | MultiSlider.Handle = MultiSliderHandle;
|
321 | return MultiSlider;
|
322 | }(common_1.AbstractPureComponent2));
|
323 | exports.MultiSlider = MultiSlider;
|
324 | function getLabelPrecision(_a) {
|
325 | var labelPrecision = _a.labelPrecision, _b = _a.stepSize, stepSize = _b === void 0 ? MultiSlider.defaultSliderProps.stepSize : _b;
|
326 |
|
327 | return labelPrecision == null ? Utils.countDecimalPlaces(stepSize) : labelPrecision;
|
328 | }
|
329 | function getSortedInteractiveHandleProps(props) {
|
330 | return getSortedHandleProps(props, function (childProps) { return childProps.interactionKind !== handleProps_1.HandleInteractionKind.NONE; });
|
331 | }
|
332 | function getSortedHandleProps(_a, predicate) {
|
333 | var children = _a.children;
|
334 | if (predicate === void 0) { predicate = function () { return true; }; }
|
335 | var maybeHandles = React.Children.map(children, function (child) {
|
336 | return Utils.isElementOfType(child, MultiSlider.Handle) && predicate(child.props) ? child.props : null;
|
337 | });
|
338 | var handles = maybeHandles != null ? maybeHandles : [];
|
339 | handles = handles.filter(function (handle) { return handle !== null; });
|
340 | handles.sort(function (left, right) { return left.value - right.value; });
|
341 | return handles;
|
342 | }
|
343 |
|
\ | No newline at end of file |