@carbon/react 1.90.0 → 1.91.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/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +986 -926
- package/es/components/Breadcrumb/Breadcrumb.Skeleton.d.ts +27 -2
- package/es/components/Breadcrumb/Breadcrumb.Skeleton.js +27 -4
- package/es/components/Breadcrumb/Breadcrumb.js +2 -1
- package/es/components/CodeSnippet/CodeSnippet.d.ts +1 -1
- package/es/components/CodeSnippet/CodeSnippet.js +1 -1
- package/es/components/ComboBox/ComboBox.js +1 -12
- package/es/components/ComboButton/index.js +1 -1
- package/es/components/ComposedModal/ComposedModal.js +1 -1
- package/es/components/ContentSwitcher/ContentSwitcher.js +2 -2
- package/es/components/Copy/Copy.d.ts +1 -1
- package/es/components/Copy/Copy.js +1 -1
- package/es/components/CopyButton/CopyButton.d.ts +1 -1
- package/es/components/CopyButton/CopyButton.js +1 -1
- package/es/components/DataTable/DataTable.d.ts +60 -15
- package/es/components/DataTable/DataTable.js +106 -179
- package/es/components/DataTable/Table.d.ts +2 -2
- package/es/components/DataTable/Table.js +1 -1
- package/es/components/DataTable/TableExpandHeader.d.ts +1 -1
- package/es/components/DataTable/TableExpandHeader.js +1 -1
- package/es/components/DatePicker/DatePicker.d.ts +0 -12
- package/es/components/DatePicker/DatePicker.js +3 -3
- package/es/components/DatePicker/plugins/rangePlugin.d.ts +19 -2
- package/es/components/DatePicker/plugins/rangePlugin.js +18 -14
- package/es/components/Dropdown/Dropdown.js +1 -12
- package/es/components/FeatureFlags/index.js +1 -0
- package/es/components/IconButton/index.js +1 -1
- package/es/components/Menu/MenuItem.d.ts +1 -1
- package/es/components/Menu/MenuItem.js +5 -5
- package/es/components/Modal/Modal.js +1 -1
- package/es/components/MultiSelect/FilterableMultiSelect.js +1 -1
- package/es/components/MultiSelect/MultiSelect.js +1 -12
- package/es/components/Notification/Notification.d.ts +6 -6
- package/es/components/Notification/Notification.js +6 -6
- package/es/components/OverflowMenu/OverflowMenu.js +1 -1
- package/es/components/OverflowMenu/next/index.js +1 -1
- package/es/components/PaginationNav/PaginationNav.d.ts +20 -0
- package/es/components/PaginationNav/PaginationNav.js +34 -5
- package/es/components/Popover/index.js +1 -1
- package/es/components/Search/Search.d.ts +4 -2
- package/es/components/Search/Search.js +5 -4
- package/es/components/Slider/Slider.d.ts +144 -188
- package/es/components/Slider/Slider.js +787 -710
- package/es/components/Slider/index.d.ts +2 -2
- package/es/components/Tabs/Tabs.d.ts +4 -0
- package/es/components/TextArea/TextArea.js +13 -6
- package/es/components/TextInput/ControlledPasswordInput.js +2 -2
- package/es/components/TextInput/PasswordInput.js +2 -2
- package/es/components/TextInput/TextInput.js +2 -2
- package/es/components/TextInput/util.d.ts +17 -5
- package/es/components/TextInput/util.js +2 -7
- package/es/components/UIShell/HeaderPanel.d.ts +1 -1
- package/es/index.d.ts +27 -24
- package/es/index.js +43 -41
- package/es/internal/defaultItemToString.d.ts +7 -0
- package/es/internal/defaultItemToString.js +17 -0
- package/es/internal/index.d.ts +1 -0
- package/es/prop-types/deprecateValuesWithin.d.ts +8 -1
- package/es/prop-types/deprecateValuesWithin.js +6 -6
- package/es/prop-types/requiredIfGivenPropIsTruthy.d.ts +8 -7
- package/es/prop-types/requiredIfGivenPropIsTruthy.js +10 -10
- package/lib/components/Breadcrumb/Breadcrumb.Skeleton.d.ts +27 -2
- package/lib/components/Breadcrumb/Breadcrumb.Skeleton.js +27 -4
- package/lib/components/Breadcrumb/Breadcrumb.js +2 -1
- package/lib/components/CodeSnippet/CodeSnippet.d.ts +1 -1
- package/lib/components/CodeSnippet/CodeSnippet.js +1 -1
- package/lib/components/ComboBox/ComboBox.js +3 -14
- package/lib/components/ComboButton/index.js +1 -1
- package/lib/components/ComposedModal/ComposedModal.js +1 -1
- package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -1
- package/lib/components/Copy/Copy.d.ts +1 -1
- package/lib/components/Copy/Copy.js +1 -1
- package/lib/components/CopyButton/CopyButton.d.ts +1 -1
- package/lib/components/CopyButton/CopyButton.js +1 -1
- package/lib/components/DataTable/DataTable.d.ts +60 -15
- package/lib/components/DataTable/DataTable.js +106 -179
- package/lib/components/DataTable/Table.d.ts +2 -2
- package/lib/components/DataTable/Table.js +1 -1
- package/lib/components/DataTable/TableExpandHeader.d.ts +1 -1
- package/lib/components/DataTable/TableExpandHeader.js +3 -3
- package/lib/components/DatePicker/DatePicker.d.ts +0 -12
- package/lib/components/DatePicker/DatePicker.js +2 -2
- package/lib/components/DatePicker/plugins/rangePlugin.d.ts +19 -2
- package/lib/components/DatePicker/plugins/rangePlugin.js +18 -16
- package/lib/components/Dropdown/Dropdown.js +3 -14
- package/lib/components/FeatureFlags/index.js +1 -0
- package/lib/components/IconButton/index.js +1 -1
- package/lib/components/Menu/MenuItem.d.ts +1 -1
- package/lib/components/Menu/MenuItem.js +6 -6
- package/lib/components/Modal/Modal.js +1 -1
- package/lib/components/MultiSelect/FilterableMultiSelect.js +8 -8
- package/lib/components/MultiSelect/MultiSelect.js +2 -13
- package/lib/components/Notification/Notification.d.ts +6 -6
- package/lib/components/Notification/Notification.js +6 -6
- package/lib/components/OverflowMenu/OverflowMenu.js +1 -1
- package/lib/components/OverflowMenu/next/index.js +1 -1
- package/lib/components/PaginationNav/PaginationNav.d.ts +20 -0
- package/lib/components/PaginationNav/PaginationNav.js +34 -5
- package/lib/components/Popover/index.js +1 -1
- package/lib/components/Search/Search.d.ts +4 -2
- package/lib/components/Search/Search.js +5 -4
- package/lib/components/Slider/Slider.d.ts +144 -188
- package/lib/components/Slider/Slider.js +784 -709
- package/lib/components/Slider/index.d.ts +2 -2
- package/lib/components/Tabs/Tabs.d.ts +4 -0
- package/lib/components/TextArea/TextArea.js +13 -6
- package/lib/components/TextInput/ControlledPasswordInput.js +1 -1
- package/lib/components/TextInput/PasswordInput.js +1 -1
- package/lib/components/TextInput/TextInput.js +1 -1
- package/lib/components/TextInput/util.d.ts +17 -5
- package/lib/components/TextInput/util.js +2 -7
- package/lib/components/UIShell/HeaderPanel.d.ts +1 -1
- package/lib/index.d.ts +27 -24
- package/lib/index.js +95 -28
- package/lib/internal/defaultItemToString.d.ts +7 -0
- package/lib/internal/defaultItemToString.js +19 -0
- package/lib/internal/index.d.ts +1 -0
- package/lib/prop-types/deprecateValuesWithin.d.ts +8 -1
- package/lib/prop-types/deprecateValuesWithin.js +6 -8
- package/lib/prop-types/requiredIfGivenPropIsTruthy.d.ts +8 -7
- package/lib/prop-types/requiredIfGivenPropIsTruthy.js +10 -12
- package/package.json +8 -7
- package/telemetry.yml +1 -2
- package/es/components/MultiSelect/tools/itemToString.d.ts +0 -1
- package/es/components/MultiSelect/tools/itemToString.js +0 -21
- package/es/components/Slider/index.js +0 -14
- package/es/internal/createClassWrapper.js +0 -23
- package/lib/components/MultiSelect/tools/itemToString.d.ts +0 -1
- package/lib/components/MultiSelect/tools/itemToString.js +0 -23
- package/lib/components/Slider/index.js +0 -20
- package/lib/internal/createClassWrapper.js +0 -25
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
11
|
-
|
|
12
10
|
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
|
|
13
11
|
var React = require('react');
|
|
14
12
|
var PropTypes = require('prop-types');
|
|
@@ -17,7 +15,6 @@ var keys = require('../../internal/keyboard/keys.js');
|
|
|
17
15
|
var match = require('../../internal/keyboard/match.js');
|
|
18
16
|
var usePrefix = require('../../internal/usePrefix.js');
|
|
19
17
|
var deprecate = require('../../prop-types/deprecate.js');
|
|
20
|
-
var index = require('../FeatureFlags/index.js');
|
|
21
18
|
var iconsReact = require('@carbon/icons-react');
|
|
22
19
|
require('../Text/index.js');
|
|
23
20
|
require('../Tooltip/DefinitionTooltip.js');
|
|
@@ -80,752 +77,834 @@ var HandlePosition = /*#__PURE__*/function (HandlePosition) {
|
|
|
80
77
|
HandlePosition["LOWER"] = "lower";
|
|
81
78
|
HandlePosition["UPPER"] = "upper";
|
|
82
79
|
return HandlePosition;
|
|
83
|
-
}(HandlePosition || {});
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
super(props);
|
|
87
|
-
_rollupPluginBabelHelpers.defineProperty(this, "state", {
|
|
88
|
-
value: this.props.value,
|
|
89
|
-
valueUpper: this.props.unstable_valueUpper,
|
|
90
|
-
left: 0,
|
|
91
|
-
leftUpper: 0,
|
|
92
|
-
needsOnRelease: false,
|
|
93
|
-
isValid: true,
|
|
94
|
-
isValidUpper: true,
|
|
95
|
-
activeHandle: undefined,
|
|
96
|
-
correctedValue: null,
|
|
97
|
-
correctedPosition: null,
|
|
98
|
-
isRtl: false
|
|
99
|
-
});
|
|
100
|
-
_rollupPluginBabelHelpers.defineProperty(this, "thumbRef", void 0);
|
|
101
|
-
_rollupPluginBabelHelpers.defineProperty(this, "thumbRefUpper", void 0);
|
|
102
|
-
_rollupPluginBabelHelpers.defineProperty(this, "filledTrackRef", void 0);
|
|
103
|
-
_rollupPluginBabelHelpers.defineProperty(this, "element", null);
|
|
104
|
-
_rollupPluginBabelHelpers.defineProperty(this, "inputId", '');
|
|
105
|
-
_rollupPluginBabelHelpers.defineProperty(this, "track", void 0);
|
|
106
|
-
_rollupPluginBabelHelpers.defineProperty(this, "handleDrag", event => {
|
|
107
|
-
if (event instanceof globalThis.MouseEvent || event instanceof globalThis.TouchEvent) {
|
|
108
|
-
this.onDrag(event);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
/**
|
|
112
|
-
* Sets up "drag" event handlers and calls `this.onDrag` in case dragging
|
|
113
|
-
* started on somewhere other than the thumb without a corresponding "move"
|
|
114
|
-
* event.
|
|
115
|
-
*/
|
|
116
|
-
_rollupPluginBabelHelpers.defineProperty(this, "onDragStart", evt => {
|
|
117
|
-
// Do nothing if component is disabled
|
|
118
|
-
if (this.props.disabled || this.props.readOnly) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// We're going to force focus on one of the handles later on here, b/c we're
|
|
123
|
-
// firing on a mousedown event, we need to call event.preventDefault() to
|
|
124
|
-
// keep the focus from leaving the HTMLElement.
|
|
125
|
-
// @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#notes
|
|
126
|
-
evt.preventDefault();
|
|
127
|
-
|
|
128
|
-
// Add drag stop handlers
|
|
129
|
-
DRAG_STOP_EVENT_TYPES.forEach(element => {
|
|
130
|
-
this.element?.ownerDocument.addEventListener(element, this.onDragStop);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// Add drag handlers
|
|
134
|
-
DRAG_EVENT_TYPES.forEach(element => {
|
|
135
|
-
this.element?.ownerDocument.addEventListener(element, this.handleDrag);
|
|
136
|
-
});
|
|
137
|
-
const clientX = this.getClientXFromEvent(evt.nativeEvent);
|
|
138
|
-
let activeHandle;
|
|
139
|
-
if (this.hasTwoHandles()) {
|
|
140
|
-
if (evt.target == this.thumbRef.current) {
|
|
141
|
-
activeHandle = HandlePosition.LOWER;
|
|
142
|
-
} else if (evt.target == this.thumbRefUpper.current) {
|
|
143
|
-
activeHandle = HandlePosition.UPPER;
|
|
144
|
-
} else if (clientX) {
|
|
145
|
-
const distanceToLower = this.calcDistanceToHandle(HandlePosition.LOWER, clientX);
|
|
146
|
-
const distanceToUpper = this.calcDistanceToHandle(HandlePosition.UPPER, clientX);
|
|
147
|
-
if (distanceToLower <= distanceToUpper) {
|
|
148
|
-
activeHandle = HandlePosition.LOWER;
|
|
149
|
-
} else {
|
|
150
|
-
activeHandle = HandlePosition.UPPER;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
80
|
+
}(HandlePosition || {}); // TODO: Delete this type and directory type the properties in the function.
|
|
81
|
+
const Slider = props => {
|
|
82
|
+
// TODO: Move destructured `props` from the IIFE to here.
|
|
154
83
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
this.setState({
|
|
169
|
-
activeHandle
|
|
170
|
-
});
|
|
84
|
+
const initialState = {
|
|
85
|
+
value: props.value,
|
|
86
|
+
valueUpper: props.unstable_valueUpper,
|
|
87
|
+
left: 0,
|
|
88
|
+
leftUpper: 0,
|
|
89
|
+
needsOnRelease: false,
|
|
90
|
+
isValid: true,
|
|
91
|
+
isValidUpper: true,
|
|
92
|
+
activeHandle: undefined,
|
|
93
|
+
correctedValue: null,
|
|
94
|
+
correctedPosition: null,
|
|
95
|
+
isRtl: false
|
|
96
|
+
};
|
|
171
97
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
* Removes "drag" and "drag stop" event handlers and calls sets the flag
|
|
178
|
-
* indicating that the `onRelease` callback should be called.
|
|
179
|
-
*/
|
|
180
|
-
_rollupPluginBabelHelpers.defineProperty(this, "onDragStop", () => {
|
|
181
|
-
// Do nothing if component is disabled
|
|
182
|
-
if (this.props.disabled || this.props.readOnly) {
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
98
|
+
// TODO: Investigate using generics on the hook.
|
|
99
|
+
const [state, setState] = React.useReducer((prev, args) => ({
|
|
100
|
+
...prev,
|
|
101
|
+
...args
|
|
102
|
+
}), initialState);
|
|
185
103
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
104
|
+
// TODO: Investigate getting rid of these references.
|
|
105
|
+
const stateRef = React.useRef(state);
|
|
106
|
+
React.useEffect(() => {
|
|
107
|
+
stateRef.current = state;
|
|
108
|
+
}, [state]);
|
|
109
|
+
const propsRef = React.useRef(props);
|
|
110
|
+
React.useEffect(() => {
|
|
111
|
+
propsRef.current = props;
|
|
112
|
+
}, [props]);
|
|
113
|
+
const thumbRef = React.useRef(null);
|
|
114
|
+
const thumbRefUpper = React.useRef(null);
|
|
115
|
+
const filledTrackRef = React.useRef(null);
|
|
116
|
+
const elementRef = React.useRef(null);
|
|
117
|
+
const trackRef = React.useRef(null);
|
|
118
|
+
const inputIdRef = React.useRef('');
|
|
190
119
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
120
|
+
// TODO: Delete this function and set its return value as the value of
|
|
121
|
+
// `twoHandles`.
|
|
122
|
+
const hasTwoHandles = () => {
|
|
123
|
+
return typeof state.valueUpper !== 'undefined';
|
|
124
|
+
};
|
|
125
|
+
const twoHandles = hasTwoHandles();
|
|
195
126
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
* accordingly.
|
|
206
|
-
*
|
|
207
|
-
* @param evt The event.
|
|
208
|
-
* @param activeHandle The first drag event call, we may have an explicit
|
|
209
|
-
* activeHandle value, which is to be used before state is used.
|
|
210
|
-
*/
|
|
211
|
-
_rollupPluginBabelHelpers.defineProperty(this, "_onDrag", (evt, activeHandle) => {
|
|
212
|
-
activeHandle = activeHandle ?? this.state.activeHandle;
|
|
213
|
-
// Do nothing if component is disabled, or we have no event.
|
|
214
|
-
if (this.props.disabled || this.props.readOnly || !evt) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
const clientX = this.getClientXFromEvent(evt);
|
|
218
|
-
const {
|
|
219
|
-
value,
|
|
220
|
-
left
|
|
221
|
-
} = this.calcValue({
|
|
222
|
-
clientX,
|
|
223
|
-
value: this.state.value
|
|
224
|
-
});
|
|
225
|
-
// If we're set to two handles, negotiate which drag handle is closest to
|
|
226
|
-
// the users' interaction.
|
|
227
|
-
if (this.hasTwoHandles() && activeHandle) {
|
|
228
|
-
this.setValueLeftForHandle(activeHandle, {
|
|
229
|
-
value: this.nearestStepValue(value),
|
|
127
|
+
/**
|
|
128
|
+
* Sets up initial slider position and value in response to component mount.
|
|
129
|
+
*/
|
|
130
|
+
React.useEffect(() => {
|
|
131
|
+
if (elementRef.current) {
|
|
132
|
+
const isRtl = document?.dir === 'rtl';
|
|
133
|
+
if (hasTwoHandles()) {
|
|
134
|
+
const {
|
|
135
|
+
value,
|
|
230
136
|
left
|
|
137
|
+
} = calcValue({
|
|
138
|
+
value: stateRef.current.value,
|
|
139
|
+
useRawValue: true
|
|
231
140
|
});
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
141
|
+
const {
|
|
142
|
+
value: valueUpper,
|
|
143
|
+
left: leftUpper
|
|
144
|
+
} = calcValue({
|
|
145
|
+
value: stateRef.current.valueUpper,
|
|
146
|
+
useRawValue: true
|
|
147
|
+
});
|
|
148
|
+
setState({
|
|
149
|
+
isRtl,
|
|
150
|
+
value,
|
|
235
151
|
left,
|
|
236
|
-
|
|
152
|
+
valueUpper,
|
|
153
|
+
leftUpper
|
|
237
154
|
});
|
|
238
|
-
}
|
|
239
|
-
this.setState({
|
|
240
|
-
correctedValue: null,
|
|
241
|
-
correctedPosition: null
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
/**
|
|
245
|
-
* Throttles calls to `this._onDrag` by limiting events to being processed at
|
|
246
|
-
* most once every `EVENT_THROTTLE` milliseconds.
|
|
247
|
-
*/
|
|
248
|
-
_rollupPluginBabelHelpers.defineProperty(this, "onDrag", throttle.throttle(this._onDrag, EVENT_THROTTLE, {
|
|
249
|
-
leading: true,
|
|
250
|
-
trailing: false
|
|
251
|
-
}));
|
|
252
|
-
/**
|
|
253
|
-
* Handles a `keydown` event by recalculating the value/thumb and setting
|
|
254
|
-
* state accordingly.
|
|
255
|
-
*/
|
|
256
|
-
_rollupPluginBabelHelpers.defineProperty(this, "onKeyDown", evt => {
|
|
257
|
-
// Do nothing if component is disabled, or we don't have a valid event
|
|
258
|
-
if (this.props.disabled || this.props.readOnly) {
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
const {
|
|
262
|
-
step = 1,
|
|
263
|
-
stepMultiplier = 4
|
|
264
|
-
} = this.props;
|
|
265
|
-
let delta = 0;
|
|
266
|
-
if (match.matches(evt, [keys.ArrowDown, keys.ArrowLeft])) {
|
|
267
|
-
delta = -step;
|
|
268
|
-
} else if (match.matches(evt, [keys.ArrowUp, keys.ArrowRight])) {
|
|
269
|
-
delta = step;
|
|
270
155
|
} else {
|
|
271
|
-
// Ignore keys we don't want to handle
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// If shift was held, account for the stepMultiplier
|
|
276
|
-
if (evt.shiftKey) {
|
|
277
|
-
delta *= stepMultiplier;
|
|
278
|
-
}
|
|
279
|
-
if (this.hasTwoHandles() && this.state.activeHandle) {
|
|
280
|
-
const currentValue = this.state.activeHandle === HandlePosition.LOWER ? this.state.value : this.state.valueUpper;
|
|
281
156
|
const {
|
|
282
157
|
value,
|
|
283
158
|
left
|
|
284
|
-
} =
|
|
285
|
-
value:
|
|
286
|
-
|
|
287
|
-
this.setValueLeftForHandle(this.state.activeHandle, {
|
|
288
|
-
value: this.nearestStepValue(value),
|
|
289
|
-
left
|
|
159
|
+
} = calcValue({
|
|
160
|
+
value: stateRef.current.value,
|
|
161
|
+
useRawValue: true
|
|
290
162
|
});
|
|
291
|
-
|
|
292
|
-
|
|
163
|
+
setState({
|
|
164
|
+
isRtl,
|
|
293
165
|
value,
|
|
294
166
|
left
|
|
295
|
-
} = this.calcValue({
|
|
296
|
-
// Ensures custom value from `<input>` won't cause skipping next stepping
|
|
297
|
-
// point with right arrow key, e.g. Typing 51 in `<input>`, moving focus
|
|
298
|
-
// onto the thumb and the hitting right arrow key should yield 52 instead
|
|
299
|
-
// of 54.
|
|
300
|
-
value: this.calcValueForDelta(this.state.value, delta, this.props.step)
|
|
301
|
-
});
|
|
302
|
-
this.setState({
|
|
303
|
-
value: this.nearestStepValue(value),
|
|
304
|
-
left,
|
|
305
|
-
isValid: true
|
|
306
167
|
});
|
|
307
168
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// Do nothing if we have no valid event, target, or value
|
|
325
|
-
if (!evt || !('target' in evt) || typeof evt.target.value !== 'string') {
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
169
|
+
}
|
|
170
|
+
return () => {
|
|
171
|
+
DRAG_STOP_EVENT_TYPES.forEach(element => elementRef.current?.ownerDocument.removeEventListener(element, onDragStop));
|
|
172
|
+
DRAG_EVENT_TYPES.forEach(element => elementRef.current?.ownerDocument.removeEventListener(element, handleDrag));
|
|
173
|
+
};
|
|
174
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
175
|
+
}, []);
|
|
176
|
+
React.useEffect(() => {
|
|
177
|
+
// TODO: Uncomment this code and delete all of the `filledTrackRef.current`
|
|
178
|
+
// checks.
|
|
179
|
+
// const el = filledTrackRef.current;
|
|
180
|
+
//
|
|
181
|
+
// if (!el) return;
|
|
328
182
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
if (
|
|
333
|
-
|
|
334
|
-
this.setValueForHandle(activeHandle, evt.target.value);
|
|
335
|
-
} else if (this.isValidValueForPosition({
|
|
336
|
-
handle: activeHandle,
|
|
337
|
-
value: targetValue,
|
|
338
|
-
min: this.props.min,
|
|
339
|
-
max: this.props.max
|
|
340
|
-
})) {
|
|
341
|
-
this.processNewInputValue(evt.target);
|
|
342
|
-
} else {
|
|
343
|
-
this.setValueForHandle(activeHandle, targetValue);
|
|
344
|
-
}
|
|
345
|
-
} else {
|
|
346
|
-
if (isNaN(targetValue)) {
|
|
347
|
-
this.setState({
|
|
348
|
-
value: evt.target.value
|
|
349
|
-
});
|
|
350
|
-
} else if (this.isValidValue({
|
|
351
|
-
value: targetValue,
|
|
352
|
-
min: this.props.min,
|
|
353
|
-
max: this.props.max
|
|
354
|
-
})) {
|
|
355
|
-
this.processNewInputValue(evt.target);
|
|
356
|
-
} else {
|
|
357
|
-
this.setState({
|
|
358
|
-
value: targetValue
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
/**
|
|
364
|
-
* Checks for validity of input value after clicking out of the input. It also
|
|
365
|
-
* Handles state change to isValid state.
|
|
366
|
-
*/
|
|
367
|
-
_rollupPluginBabelHelpers.defineProperty(this, "onBlur", evt => {
|
|
368
|
-
// Do nothing if we have no valid event, target, or value
|
|
369
|
-
if (!evt || !('target' in evt) || typeof evt.target.value !== 'string') {
|
|
370
|
-
return;
|
|
183
|
+
// Fire onChange event handler if present, if there's a usable value, and
|
|
184
|
+
// if the value is different from the last one
|
|
185
|
+
if (hasTwoHandles()) {
|
|
186
|
+
if (filledTrackRef.current) {
|
|
187
|
+
filledTrackRef.current.style.transform = state.isRtl ? `translate(${100 - state.leftUpper}%, -50%) scaleX(${(state.leftUpper - state.left) / 100})` : `translate(${state.left}%, -50%) scaleX(${(state.leftUpper - state.left) / 100})`;
|
|
371
188
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
this.processNewInputValue(evt.target);
|
|
376
|
-
this.props.onBlur?.({
|
|
377
|
-
value: targetValue,
|
|
378
|
-
handlePosition: evt.target.dataset.handlePosition
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
_rollupPluginBabelHelpers.defineProperty(this, "onInputKeyDown", evt => {
|
|
382
|
-
// Do nothing if component is disabled, or we don't have a valid event.
|
|
383
|
-
if (this.props.disabled || this.props.readOnly || !(evt.target instanceof HTMLInputElement)) {
|
|
384
|
-
return;
|
|
189
|
+
} else {
|
|
190
|
+
if (filledTrackRef.current) {
|
|
191
|
+
filledTrackRef.current.style.transform = state.isRtl ? `translate(100%, -50%) scaleX(-${state.left / 100})` : `translate(0%, -50%) scaleX(${state.left / 100})`;
|
|
385
192
|
}
|
|
193
|
+
}
|
|
194
|
+
// TODO: Investigate whether the missing dependency should be added.
|
|
195
|
+
//
|
|
196
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
197
|
+
}, [state.left, state.leftUpper, state.isRtl]);
|
|
386
198
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
_rollupPluginBabelHelpers.defineProperty(this, "processNewInputValue", input => {
|
|
396
|
-
this.setState({
|
|
397
|
-
correctedValue: null,
|
|
398
|
-
correctedPosition: null
|
|
199
|
+
// Fire onChange when value(s) change
|
|
200
|
+
const prevValsRef = React.useRef(null);
|
|
201
|
+
React.useEffect(() => {
|
|
202
|
+
const prev = prevValsRef.current;
|
|
203
|
+
if (prev && (prev.value !== state.value || prev.valueUpper !== state.valueUpper) && typeof props.onChange === 'function') {
|
|
204
|
+
props.onChange({
|
|
205
|
+
value: state.value,
|
|
206
|
+
valueUpper: state.valueUpper
|
|
399
207
|
});
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
416
|
-
this.setState({
|
|
417
|
-
isValid: validity
|
|
208
|
+
}
|
|
209
|
+
prevValsRef.current = {
|
|
210
|
+
value: state.value,
|
|
211
|
+
valueUpper: state.valueUpper
|
|
212
|
+
};
|
|
213
|
+
// TODO: Investigate whether the missing dependency should be added.
|
|
214
|
+
//
|
|
215
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
216
|
+
}, [state.value, state.valueUpper, props.onChange]);
|
|
217
|
+
React.useEffect(() => {
|
|
218
|
+
// Fire onRelease event handler if present and if needed
|
|
219
|
+
if (state.needsOnRelease && typeof props.onRelease === 'function') {
|
|
220
|
+
props.onRelease({
|
|
221
|
+
value: state.value,
|
|
222
|
+
valueUpper: state.valueUpper
|
|
418
223
|
});
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
224
|
+
// Reset the flag
|
|
225
|
+
setState({
|
|
226
|
+
needsOnRelease: false
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
// TODO: Investigate whether the missing dependency should be added.
|
|
230
|
+
//
|
|
231
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
232
|
+
}, [state.needsOnRelease, state.value, state.valueUpper, props.onRelease]);
|
|
233
|
+
const prevSyncKeysRef = React.useRef(null);
|
|
234
|
+
React.useEffect(() => {
|
|
235
|
+
const prev = prevSyncKeysRef.current;
|
|
236
|
+
const next = [props.value, props.unstable_valueUpper, props.max, props.min];
|
|
237
|
+
|
|
238
|
+
// If value from props does not change, do nothing here.
|
|
239
|
+
// Otherwise, do prop -> state sync without "value capping".
|
|
240
|
+
if (!prev || prev[0] !== next[0] || prev[1] !== next[1] || prev[2] !== next[2] || prev[3] !== next[3]) {
|
|
241
|
+
setState(calcValue({
|
|
242
|
+
value: props.value,
|
|
243
|
+
useRawValue: true
|
|
244
|
+
}));
|
|
245
|
+
if (typeof props.unstable_valueUpper !== 'undefined') {
|
|
441
246
|
const {
|
|
442
|
-
value,
|
|
443
|
-
left
|
|
444
|
-
} =
|
|
445
|
-
value:
|
|
247
|
+
value: valueUpper,
|
|
248
|
+
left: leftUpper
|
|
249
|
+
} = calcValue({
|
|
250
|
+
value: props.unstable_valueUpper,
|
|
446
251
|
useRawValue: true
|
|
447
252
|
});
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
});
|
|
458
|
-
}
|
|
253
|
+
setState({
|
|
254
|
+
valueUpper,
|
|
255
|
+
leftUpper
|
|
256
|
+
});
|
|
257
|
+
} else {
|
|
258
|
+
setState({
|
|
259
|
+
valueUpper: undefined,
|
|
260
|
+
leftUpper: undefined
|
|
261
|
+
});
|
|
459
262
|
}
|
|
263
|
+
prevSyncKeysRef.current = next;
|
|
264
|
+
}
|
|
265
|
+
// TODO: Investigate whether the missing dependency should be added.
|
|
266
|
+
//
|
|
267
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
268
|
+
}, [props.value, props.unstable_valueUpper, props.max, props.min]);
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Rounds a given value to the nearest step defined by the slider's `step`
|
|
272
|
+
* prop.
|
|
273
|
+
*
|
|
274
|
+
* @param value - The value to adjust to the nearest step. Defaults to `0`.
|
|
275
|
+
* @returns The value rounded to the precision determined by the step.
|
|
276
|
+
*/
|
|
277
|
+
const nearestStepValue = (value = 0) => {
|
|
278
|
+
// TODO: Use a nullish coalescing operator.
|
|
279
|
+
const decimals = (props.step?.toString().split('.')[1] || '').length;
|
|
280
|
+
return Number(value.toFixed(decimals));
|
|
281
|
+
};
|
|
282
|
+
const handleDrag = event => {
|
|
283
|
+
if (event instanceof globalThis.MouseEvent || event instanceof globalThis.TouchEvent) {
|
|
284
|
+
onDrag(event);
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Sets up "drag" event handlers and calls `onDrag` in case dragging
|
|
290
|
+
* started on somewhere other than the thumb without a corresponding "move"
|
|
291
|
+
* event.
|
|
292
|
+
*/
|
|
293
|
+
const onDragStart = evt => {
|
|
294
|
+
// Do nothing if component is disabled
|
|
295
|
+
if (props.disabled || props.readOnly) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// We're going to force focus on one of the handles later on here, b/c we're
|
|
300
|
+
// firing on a mousedown event, we need to call event.preventDefault() to
|
|
301
|
+
// keep the focus from leaving the HTMLElement.
|
|
302
|
+
// @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#notes
|
|
303
|
+
evt.preventDefault();
|
|
304
|
+
|
|
305
|
+
// TODO: Abstract `elementRef.current?.ownerDocument` to a variable that can
|
|
306
|
+
// be used here and everywhere else in this file.
|
|
307
|
+
|
|
308
|
+
// Add drag stop handlers
|
|
309
|
+
DRAG_STOP_EVENT_TYPES.forEach(element => {
|
|
310
|
+
elementRef.current?.ownerDocument.addEventListener(element, onDragStop);
|
|
460
311
|
});
|
|
461
|
-
_rollupPluginBabelHelpers.defineProperty(this, "calcLeftPercent", ({
|
|
462
|
-
clientX,
|
|
463
|
-
value,
|
|
464
|
-
range
|
|
465
|
-
}) => {
|
|
466
|
-
const boundingRect = this.element?.getBoundingClientRect?.();
|
|
467
|
-
let width = boundingRect ? boundingRect.right - boundingRect.left : 0;
|
|
468
312
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
313
|
+
// Add drag handlers
|
|
314
|
+
DRAG_EVENT_TYPES.forEach(element => {
|
|
315
|
+
elementRef.current?.ownerDocument.addEventListener(element, handleDrag);
|
|
316
|
+
});
|
|
317
|
+
const clientX = getClientXFromEvent(evt.nativeEvent);
|
|
318
|
+
let activeHandle;
|
|
319
|
+
if (hasTwoHandles()) {
|
|
320
|
+
if (evt.target == thumbRef.current) {
|
|
321
|
+
activeHandle = HandlePosition.LOWER;
|
|
322
|
+
} else if (evt.target == thumbRefUpper.current) {
|
|
323
|
+
activeHandle = HandlePosition.UPPER;
|
|
324
|
+
} else if (clientX) {
|
|
325
|
+
const distanceToLower = calcDistanceToHandle(HandlePosition.LOWER, clientX);
|
|
326
|
+
const distanceToUpper = calcDistanceToHandle(HandlePosition.UPPER, clientX);
|
|
327
|
+
if (distanceToLower <= distanceToUpper) {
|
|
328
|
+
activeHandle = HandlePosition.LOWER;
|
|
329
|
+
} else {
|
|
330
|
+
activeHandle = HandlePosition.UPPER;
|
|
331
|
+
}
|
|
472
332
|
}
|
|
333
|
+
}
|
|
473
334
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
335
|
+
// Force focus to the appropriate handle.
|
|
336
|
+
const focusOptions = {
|
|
337
|
+
preventScroll: true
|
|
338
|
+
};
|
|
339
|
+
if (hasTwoHandles()) {
|
|
340
|
+
if (thumbRef.current && activeHandle === HandlePosition.LOWER) {
|
|
341
|
+
thumbRef.current.focus(focusOptions);
|
|
342
|
+
} else if (thumbRefUpper.current && activeHandle === HandlePosition.UPPER) {
|
|
343
|
+
thumbRefUpper.current.focus(focusOptions);
|
|
482
344
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
345
|
+
} else if (thumbRef.current) {
|
|
346
|
+
thumbRef.current.focus(focusOptions);
|
|
347
|
+
}
|
|
348
|
+
setState({
|
|
349
|
+
activeHandle
|
|
486
350
|
});
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
discretePercent
|
|
508
|
-
};
|
|
351
|
+
|
|
352
|
+
// Perform first recalculation since we probably didn't click exactly in the
|
|
353
|
+
// middle of the thumb.
|
|
354
|
+
onDrag(evt.nativeEvent, activeHandle);
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Removes "drag" and "drag stop" event handlers and calls sets the flag
|
|
359
|
+
* indicating that the `onRelease` callback should be called.
|
|
360
|
+
*/
|
|
361
|
+
const onDragStop = () => {
|
|
362
|
+
// Do nothing if component is disabled
|
|
363
|
+
if (props.disabled || props.readOnly) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// TODO: Rename parameters in `DRAG_*` loops to `type`.
|
|
368
|
+
// Remove drag stop handlers
|
|
369
|
+
DRAG_STOP_EVENT_TYPES.forEach(element => {
|
|
370
|
+
elementRef.current?.ownerDocument.removeEventListener(element, onDragStop);
|
|
509
371
|
});
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
372
|
+
|
|
373
|
+
// Remove drag handlers
|
|
374
|
+
DRAG_EVENT_TYPES.forEach(element => {
|
|
375
|
+
elementRef.current?.ownerDocument.removeEventListener(element, handleDrag);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// Set needsOnRelease flag so event fires on next update.
|
|
379
|
+
setState({
|
|
380
|
+
needsOnRelease: true,
|
|
381
|
+
isValid: true,
|
|
382
|
+
isValidUpper: true
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
// TODO: Rename this reference.
|
|
387
|
+
/**
|
|
388
|
+
* Handles a "drag" event by recalculating the value/thumb and setting state
|
|
389
|
+
* accordingly.
|
|
390
|
+
*
|
|
391
|
+
* @param evt The event.
|
|
392
|
+
* @param activeHandle The first drag event call, we may have an explicit
|
|
393
|
+
* activeHandle value, which is to be used before state is used.
|
|
394
|
+
*/
|
|
395
|
+
const _onDragRef = React.useRef(null);
|
|
396
|
+
_onDragRef.current = (evt, activeHandle) => {
|
|
397
|
+
activeHandle = activeHandle ?? stateRef.current.activeHandle;
|
|
398
|
+
// Do nothing if component is disabled, or we have no event.
|
|
399
|
+
if (propsRef.current.disabled || propsRef.current.readOnly || !evt) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
const clientX = getClientXFromEvent(evt);
|
|
403
|
+
const {
|
|
516
404
|
value,
|
|
517
|
-
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
405
|
+
left
|
|
406
|
+
} = calcValue({
|
|
407
|
+
clientX,
|
|
408
|
+
value: stateRef.current.value
|
|
409
|
+
});
|
|
410
|
+
// If we're set to two handles, negotiate which drag handle is closest to
|
|
411
|
+
// the users' interaction.
|
|
412
|
+
if (hasTwoHandles() && activeHandle) {
|
|
413
|
+
setValueLeftForHandle(activeHandle, {
|
|
414
|
+
value: nearestStepValue(value),
|
|
415
|
+
left
|
|
524
416
|
});
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
417
|
+
} else {
|
|
418
|
+
setState({
|
|
419
|
+
value: nearestStepValue(value),
|
|
420
|
+
left,
|
|
421
|
+
isValid: true
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
// TODO: Investigate if it would be better to not call `setState`
|
|
425
|
+
// back-to-back here and in other places.
|
|
426
|
+
setState({
|
|
427
|
+
correctedValue: null,
|
|
428
|
+
correctedPosition: null
|
|
429
|
+
});
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Throttles calls to `_onDrag` by limiting events to being processed at
|
|
434
|
+
* most once every `EVENT_THROTTLE` milliseconds.
|
|
435
|
+
*/
|
|
436
|
+
const onDrag = React.useMemo(() => throttle.throttle((evt, activeHandle) => {
|
|
437
|
+
_onDragRef.current?.(evt, activeHandle);
|
|
438
|
+
}, EVENT_THROTTLE, {
|
|
439
|
+
leading: true,
|
|
440
|
+
trailing: false
|
|
441
|
+
}), []);
|
|
533
442
|
|
|
534
|
-
|
|
443
|
+
/**
|
|
444
|
+
* Handles a `keydown` event by recalculating the value/thumb and setting
|
|
445
|
+
* state accordingly.
|
|
446
|
+
*/
|
|
447
|
+
const onKeyDown = evt => {
|
|
448
|
+
// Do nothing if component is disabled, or we don't have a valid event
|
|
449
|
+
if (props.disabled || props.readOnly) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
const {
|
|
453
|
+
step = 1,
|
|
454
|
+
stepMultiplier = 4
|
|
455
|
+
} = props;
|
|
456
|
+
let delta = 0;
|
|
457
|
+
if (match.matches(evt, [keys.ArrowDown, keys.ArrowLeft])) {
|
|
458
|
+
delta = -step;
|
|
459
|
+
} else if (match.matches(evt, [keys.ArrowUp, keys.ArrowRight])) {
|
|
460
|
+
delta = step;
|
|
461
|
+
} else {
|
|
462
|
+
// Ignore keys we don't want to handle
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// If shift was held, account for the stepMultiplier
|
|
467
|
+
if (evt.shiftKey) {
|
|
468
|
+
delta *= stepMultiplier;
|
|
469
|
+
}
|
|
470
|
+
if (hasTwoHandles() && state.activeHandle) {
|
|
471
|
+
const currentValue = state.activeHandle === HandlePosition.LOWER ? state.value : state.valueUpper;
|
|
535
472
|
const {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
} =
|
|
539
|
-
|
|
473
|
+
value,
|
|
474
|
+
left
|
|
475
|
+
} = calcValue({
|
|
476
|
+
value: calcValueForDelta(currentValue ?? props.min, delta, props.step)
|
|
540
477
|
});
|
|
541
|
-
|
|
542
|
-
value:
|
|
543
|
-
left
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
_rollupPluginBabelHelpers.defineProperty(this, "calcDistanceToHandle", (handle, clientX) => {
|
|
547
|
-
const handleBoundingRect = this.getHandleBoundingRect(handle);
|
|
548
|
-
// x co-ordinate of the midpoint.
|
|
549
|
-
const handleX = handleBoundingRect.left + handleBoundingRect.width / 2;
|
|
550
|
-
return Math.abs(handleX - clientX);
|
|
551
|
-
});
|
|
552
|
-
/**
|
|
553
|
-
* Calculates a new slider value based on the current value, a change delta,
|
|
554
|
-
* and a step.
|
|
555
|
-
*
|
|
556
|
-
* @param currentValue - The starting value from which the slider is moving.
|
|
557
|
-
* @param delta - The amount to adjust the current value by.
|
|
558
|
-
* @param step - The step. Defaults to `1`.
|
|
559
|
-
* @returns The new slider value, rounded to the same number of decimal places
|
|
560
|
-
* as the step.
|
|
561
|
-
*/
|
|
562
|
-
_rollupPluginBabelHelpers.defineProperty(this, "calcValueForDelta", (currentValue, delta, step = 1) => {
|
|
563
|
-
const base = delta > 0 ? Math.floor(currentValue / step) * step : currentValue;
|
|
564
|
-
const newValue = base + delta;
|
|
565
|
-
const decimals = (step.toString().split('.')[1] || '').length;
|
|
566
|
-
return Number(newValue.toFixed(decimals));
|
|
567
|
-
});
|
|
568
|
-
/**
|
|
569
|
-
* Sets state relevant to the given handle position.
|
|
570
|
-
*
|
|
571
|
-
* Guards against setting either lower or upper values beyond its counterpart.
|
|
572
|
-
*/
|
|
573
|
-
_rollupPluginBabelHelpers.defineProperty(this, "setValueLeftForHandle", (handle, {
|
|
574
|
-
value: newValue,
|
|
575
|
-
left: newLeft
|
|
576
|
-
}) => {
|
|
478
|
+
setValueLeftForHandle(state.activeHandle, {
|
|
479
|
+
value: nearestStepValue(value),
|
|
480
|
+
left
|
|
481
|
+
});
|
|
482
|
+
} else {
|
|
577
483
|
const {
|
|
578
484
|
value,
|
|
579
|
-
|
|
485
|
+
left
|
|
486
|
+
} = calcValue({
|
|
487
|
+
// Ensures custom value from `<input>` won't cause skipping next stepping
|
|
488
|
+
// point with right arrow key, e.g. Typing 51 in `<input>`, moving focus
|
|
489
|
+
// onto the thumb and the hitting right arrow key should yield 52 instead
|
|
490
|
+
// of 54.
|
|
491
|
+
value: calcValueForDelta(state.value, delta, props.step)
|
|
492
|
+
});
|
|
493
|
+
setState({
|
|
494
|
+
value: nearestStepValue(value),
|
|
580
495
|
left,
|
|
581
|
-
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
496
|
+
isValid: true
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
setState({
|
|
500
|
+
correctedValue: null,
|
|
501
|
+
correctedPosition: null
|
|
502
|
+
});
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Provides the two-way binding for the input field of the Slider. It also
|
|
507
|
+
* Handles a change to the input field by recalculating the value/thumb and
|
|
508
|
+
* setting state accordingly.
|
|
509
|
+
*/
|
|
510
|
+
const onChangeInput = evt => {
|
|
511
|
+
// Do nothing if component is disabled
|
|
512
|
+
if (props.disabled || props.readOnly) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// Do nothing if we have no valid event, target, or value
|
|
517
|
+
if (!evt || !('target' in evt) || typeof evt.target.value !== 'string') {
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Avoid calling calcValue for invalid numbers, but still update the state.
|
|
522
|
+
const activeHandle = evt.target.dataset.handlePosition ?? HandlePosition.LOWER;
|
|
523
|
+
const targetValue = Number.parseFloat(evt.target.value);
|
|
524
|
+
if (hasTwoHandles()) {
|
|
525
|
+
if (isNaN(targetValue)) {
|
|
526
|
+
setValueForHandle(activeHandle, evt.target.value);
|
|
527
|
+
} else if (isValidValueForPosition({
|
|
528
|
+
handle: activeHandle,
|
|
529
|
+
value: targetValue,
|
|
530
|
+
min: props.min,
|
|
531
|
+
max: props.max
|
|
532
|
+
})) {
|
|
533
|
+
processNewInputValue(evt.target);
|
|
534
|
+
} else {
|
|
535
|
+
setValueForHandle(activeHandle, targetValue);
|
|
536
|
+
}
|
|
537
|
+
} else {
|
|
538
|
+
if (isNaN(targetValue)) {
|
|
539
|
+
// TODO: Address this error
|
|
540
|
+
//
|
|
541
|
+
// @ts-expect-error - Passing a string to something that expects a
|
|
542
|
+
// number.
|
|
543
|
+
setState({
|
|
544
|
+
value: evt.target.value
|
|
589
545
|
});
|
|
546
|
+
} else if (isValidValue({
|
|
547
|
+
value: targetValue,
|
|
548
|
+
min: props.min,
|
|
549
|
+
max: props.max
|
|
550
|
+
})) {
|
|
551
|
+
processNewInputValue(evt.target);
|
|
590
552
|
} else {
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
leftUpper: value && newValue < value ? left : newLeft,
|
|
594
|
-
isValidUpper: true
|
|
553
|
+
setState({
|
|
554
|
+
value: targetValue
|
|
595
555
|
});
|
|
596
556
|
}
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Checks for validity of input value after clicking out of the input. It also
|
|
562
|
+
* Handles state change to isValid state.
|
|
563
|
+
*/
|
|
564
|
+
const onBlurInput = evt => {
|
|
565
|
+
// Do nothing if we have no valid event, target, or value
|
|
566
|
+
if (!evt || !('target' in evt) || typeof evt.target.value !== 'string') {
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
const {
|
|
570
|
+
value: targetValue
|
|
571
|
+
} = evt.target;
|
|
572
|
+
processNewInputValue(evt.target);
|
|
573
|
+
props.onBlur?.({
|
|
574
|
+
value: targetValue,
|
|
575
|
+
handlePosition: evt.target.dataset.handlePosition
|
|
597
576
|
});
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
577
|
+
};
|
|
578
|
+
const onInputKeyDown = evt => {
|
|
579
|
+
// Do nothing if component is disabled, or we don't have a valid event.
|
|
580
|
+
if (props.disabled || props.readOnly || !(evt.target instanceof HTMLInputElement)) {
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Do nothing if we have no valid event, target, or value.
|
|
585
|
+
if (!evt || !('target' in evt) || typeof evt.target.value !== 'string') {
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
if (match.matches(evt, [keys.Enter])) {
|
|
589
|
+
processNewInputValue(evt.target);
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
const processNewInputValue = input => {
|
|
593
|
+
setState({
|
|
594
|
+
correctedValue: null,
|
|
595
|
+
correctedPosition: null
|
|
596
|
+
});
|
|
597
|
+
const targetValue = Number.parseFloat(input.value);
|
|
598
|
+
const validity = !isNaN(targetValue);
|
|
599
|
+
|
|
600
|
+
// When there are two handles, we'll also have the data-handle-position
|
|
601
|
+
// attribute to consider the other value before settling on the validity to
|
|
602
|
+
// set.
|
|
603
|
+
const handlePosition = input.dataset.handlePosition;
|
|
604
|
+
if (handlePosition === HandlePosition.LOWER) {
|
|
605
|
+
setState({
|
|
606
|
+
isValid: validity
|
|
607
|
+
});
|
|
608
|
+
} else if (handlePosition === HandlePosition.UPPER) {
|
|
609
|
+
setState({
|
|
610
|
+
isValidUpper: validity
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
setState({
|
|
614
|
+
isValid: validity
|
|
615
|
+
});
|
|
616
|
+
if (validity) {
|
|
617
|
+
const adjustedValue = handlePosition ? getAdjustedValueForPosition({
|
|
618
|
+
handle: handlePosition,
|
|
619
|
+
value: targetValue,
|
|
620
|
+
min: props.min,
|
|
621
|
+
max: props.max
|
|
622
|
+
}) : getAdjustedValue({
|
|
623
|
+
value: targetValue,
|
|
624
|
+
min: props.min,
|
|
625
|
+
max: props.max
|
|
626
|
+
});
|
|
627
|
+
if (adjustedValue !== targetValue) {
|
|
628
|
+
setState({
|
|
629
|
+
correctedValue: targetValue.toString(),
|
|
630
|
+
correctedPosition: handlePosition ?? null
|
|
603
631
|
});
|
|
604
632
|
} else {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
633
|
+
setState({
|
|
634
|
+
correctedValue: null,
|
|
635
|
+
correctedPosition: null
|
|
608
636
|
});
|
|
609
637
|
}
|
|
610
|
-
});
|
|
611
|
-
_rollupPluginBabelHelpers.defineProperty(this, "isValidValueForPosition", ({
|
|
612
|
-
handle,
|
|
613
|
-
value: newValue,
|
|
614
|
-
min,
|
|
615
|
-
max
|
|
616
|
-
}) => {
|
|
617
638
|
const {
|
|
618
639
|
value,
|
|
619
|
-
|
|
620
|
-
} =
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
640
|
+
left
|
|
641
|
+
} = calcValue({
|
|
642
|
+
value: adjustedValue,
|
|
643
|
+
useRawValue: true
|
|
644
|
+
});
|
|
645
|
+
if (handlePosition) {
|
|
646
|
+
setValueLeftForHandle(handlePosition, {
|
|
647
|
+
value: nearestStepValue(value),
|
|
648
|
+
left
|
|
649
|
+
});
|
|
650
|
+
} else {
|
|
651
|
+
setState({
|
|
652
|
+
value,
|
|
653
|
+
left
|
|
654
|
+
});
|
|
632
655
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
const calcLeftPercent = ({
|
|
659
|
+
clientX,
|
|
660
|
+
value,
|
|
661
|
+
range
|
|
662
|
+
}) => {
|
|
663
|
+
// TODO: Delete the optional chaining operator after `getBoundingClientRect`.
|
|
664
|
+
const boundingRect = elementRef.current?.getBoundingClientRect?.();
|
|
665
|
+
let width = boundingRect ? boundingRect.right - boundingRect.left : 0;
|
|
666
|
+
|
|
667
|
+
// Enforce a minimum width of at least 1 for calculations
|
|
668
|
+
if (width <= 0) {
|
|
669
|
+
width = 1;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// If a clientX is specified, use it to calculate the leftPercent. If not,
|
|
673
|
+
// use the provided value to calculate it instead.
|
|
674
|
+
if (clientX) {
|
|
675
|
+
const leftOffset = state.isRtl ? (boundingRect?.right ?? 0) - clientX : clientX - (boundingRect?.left ?? 0);
|
|
676
|
+
return leftOffset / width;
|
|
677
|
+
} else if (value !== null && typeof value !== 'undefined' && range) {
|
|
678
|
+
// Prevent NaN calculation if the range is 0.
|
|
679
|
+
return range === 0 ? 0 : (value - props.min) / range;
|
|
680
|
+
}
|
|
681
|
+
// We should never end up in this scenario, but in case we do, and to
|
|
682
|
+
// re-assure Typescript, return 0.
|
|
683
|
+
return 0;
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Calculates the discrete value (snapped to the nearest step) along
|
|
688
|
+
* with the corresponding handle position percentage.
|
|
689
|
+
*/
|
|
690
|
+
const calcDiscreteValueAndPercent = ({
|
|
691
|
+
leftPercent
|
|
692
|
+
}) => {
|
|
693
|
+
const {
|
|
694
|
+
step = 1,
|
|
645
695
|
min,
|
|
646
696
|
max
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
697
|
+
} = props;
|
|
698
|
+
const numSteps = Math.floor((max - min) / step) + ((max - min) % step === 0 ? 1 : 2);
|
|
699
|
+
/** Index of the step that corresponds to `leftPercent`. */
|
|
700
|
+
const stepIndex = Math.round(leftPercent * (numSteps - 1));
|
|
701
|
+
const discreteValue = stepIndex === numSteps - 1 ? max : min + step * stepIndex;
|
|
702
|
+
/** Percentage corresponding to the step index. */
|
|
703
|
+
const discretePercent = stepIndex / (numSteps - 1);
|
|
704
|
+
return {
|
|
705
|
+
discreteValue,
|
|
706
|
+
discretePercent
|
|
707
|
+
};
|
|
708
|
+
};
|
|
657
709
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
710
|
+
/**
|
|
711
|
+
* Calculates the slider's value and handle position based on either a
|
|
712
|
+
* mouse/touch event or an explicit value.
|
|
713
|
+
*/
|
|
714
|
+
const calcValue = ({
|
|
715
|
+
clientX,
|
|
716
|
+
value,
|
|
717
|
+
useRawValue
|
|
718
|
+
}) => {
|
|
719
|
+
const range = props.max - props.min;
|
|
720
|
+
const leftPercentRaw = calcLeftPercent({
|
|
721
|
+
clientX,
|
|
667
722
|
value,
|
|
668
|
-
|
|
669
|
-
max
|
|
670
|
-
}) => {
|
|
671
|
-
if (value < min) {
|
|
672
|
-
value = min;
|
|
673
|
-
}
|
|
674
|
-
if (value > max) {
|
|
675
|
-
value = max;
|
|
676
|
-
}
|
|
677
|
-
return value;
|
|
723
|
+
range
|
|
678
724
|
});
|
|
679
|
-
/**
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
725
|
+
/** `leftPercentRaw` clamped between 0 and 1. */
|
|
726
|
+
const leftPercent = clamp.clamp(leftPercentRaw, 0, 1);
|
|
727
|
+
if (useRawValue) {
|
|
728
|
+
return {
|
|
729
|
+
value,
|
|
730
|
+
left: leftPercent * 100
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// Use the discrete value and percentage for snapping.
|
|
735
|
+
const {
|
|
736
|
+
discreteValue,
|
|
737
|
+
discretePercent
|
|
738
|
+
} = calcDiscreteValueAndPercent({
|
|
739
|
+
leftPercent
|
|
692
740
|
});
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
741
|
+
return {
|
|
742
|
+
value: discreteValue,
|
|
743
|
+
left: discretePercent * 100
|
|
744
|
+
};
|
|
745
|
+
};
|
|
746
|
+
const calcDistanceToHandle = (handle, clientX) => {
|
|
747
|
+
const handleBoundingRect = getHandleBoundingRect(handle);
|
|
748
|
+
/** x-coordinate of the midpoint. */
|
|
749
|
+
const handleX = handleBoundingRect.left + handleBoundingRect.width / 2;
|
|
750
|
+
return Math.abs(handleX - clientX);
|
|
751
|
+
};
|
|
697
752
|
|
|
698
753
|
/**
|
|
699
|
-
*
|
|
754
|
+
* Calculates a new slider value based on the current value, a change delta,
|
|
755
|
+
* and a step.
|
|
756
|
+
*
|
|
757
|
+
* @param currentValue - The starting value from which the slider is moving.
|
|
758
|
+
* @param delta - The amount to adjust the current value by.
|
|
759
|
+
* @param step - The step. Defaults to `1`.
|
|
760
|
+
* @returns The new slider value, rounded to the same number of decimal places
|
|
761
|
+
* as the step.
|
|
700
762
|
*/
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
} = this.calcValue({
|
|
709
|
-
value: this.state.value,
|
|
710
|
-
useRawValue: true
|
|
711
|
-
});
|
|
712
|
-
const {
|
|
713
|
-
value: valueUpper,
|
|
714
|
-
left: leftUpper
|
|
715
|
-
} = this.calcValue({
|
|
716
|
-
value: this.state.valueUpper,
|
|
717
|
-
useRawValue: true
|
|
718
|
-
});
|
|
719
|
-
this.setState({
|
|
720
|
-
isRtl,
|
|
721
|
-
value,
|
|
722
|
-
left,
|
|
723
|
-
valueUpper,
|
|
724
|
-
leftUpper
|
|
725
|
-
});
|
|
726
|
-
if (this.filledTrackRef.current) {
|
|
727
|
-
this.filledTrackRef.current.style.transform = this.state.isRtl ? `translate(${100 - this.state.leftUpper}%, -50%) scaleX(${(this.state.leftUpper - this.state.left) / 100})` : `translate(${this.state.left}%, -50%) scaleX(${(this.state.leftUpper - this.state.left) / 100})`;
|
|
728
|
-
}
|
|
729
|
-
} else {
|
|
730
|
-
const {
|
|
731
|
-
value,
|
|
732
|
-
left
|
|
733
|
-
} = this.calcValue({
|
|
734
|
-
value: this.state.value,
|
|
735
|
-
useRawValue: true
|
|
736
|
-
});
|
|
737
|
-
this.setState({
|
|
738
|
-
isRtl,
|
|
739
|
-
value,
|
|
740
|
-
left
|
|
741
|
-
});
|
|
742
|
-
if (this.filledTrackRef.current) {
|
|
743
|
-
this.filledTrackRef.current.style.transform = this.state.isRtl ? `translate(100%, -50%) scaleX(-${this.state.left / 100})` : `translate(0%, -50%) scaleX(${this.state.left / 100})`;
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
}
|
|
763
|
+
const calcValueForDelta = (currentValue, delta, step = 1) => {
|
|
764
|
+
const base = delta > 0 ? Math.floor(currentValue / step) * step : currentValue;
|
|
765
|
+
const newValue = base + delta;
|
|
766
|
+
// TODO: Why is the logical OR needed here?
|
|
767
|
+
const decimals = (step.toString().split('.')[1] || '').length;
|
|
768
|
+
return Number(newValue.toFixed(decimals));
|
|
769
|
+
};
|
|
748
770
|
|
|
749
771
|
/**
|
|
750
|
-
*
|
|
751
|
-
* response to state changes.
|
|
772
|
+
* Sets state relevant to the given handle position.
|
|
752
773
|
*
|
|
753
|
-
*
|
|
754
|
-
* @param {*} prevState The previous Slider state, used to see if callbacks
|
|
755
|
-
* should be called.
|
|
774
|
+
* Guards against setting either lower or upper values beyond its counterpart.
|
|
756
775
|
*/
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
776
|
+
const setValueLeftForHandle = (handle, {
|
|
777
|
+
value: newValue,
|
|
778
|
+
left: newLeft
|
|
779
|
+
}) => {
|
|
780
|
+
const {
|
|
781
|
+
value,
|
|
782
|
+
valueUpper,
|
|
783
|
+
left,
|
|
784
|
+
leftUpper
|
|
785
|
+
} = state;
|
|
786
|
+
if (handle === HandlePosition.LOWER) {
|
|
787
|
+
// Don't allow higher than the upper handle.
|
|
788
|
+
setState({
|
|
789
|
+
value: valueUpper && newValue > valueUpper ? valueUpper : newValue,
|
|
790
|
+
left: valueUpper && newValue > valueUpper ? leftUpper : newLeft,
|
|
791
|
+
isValid: true
|
|
792
|
+
});
|
|
764
793
|
} else {
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
if ((prevState.value !== this.state.value || prevState.valueUpper !== this.state.valueUpper) && typeof this.props.onChange === 'function') {
|
|
770
|
-
this.props.onChange({
|
|
771
|
-
value: this.state.value,
|
|
772
|
-
valueUpper: this.state.valueUpper
|
|
794
|
+
setState({
|
|
795
|
+
valueUpper: value && newValue < value ? value : newValue,
|
|
796
|
+
leftUpper: value && newValue < value ? left : newLeft,
|
|
797
|
+
isValidUpper: true
|
|
773
798
|
});
|
|
774
799
|
}
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
if (
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
800
|
+
};
|
|
801
|
+
const setValueForHandle = (handle, value) => {
|
|
802
|
+
if (handle === HandlePosition.LOWER) {
|
|
803
|
+
setState({
|
|
804
|
+
// TODO: Address this error
|
|
805
|
+
//
|
|
806
|
+
// @ts-expect-error - Passing a string to something that expects a
|
|
807
|
+
// number.
|
|
808
|
+
value,
|
|
809
|
+
isValid: true
|
|
781
810
|
});
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
811
|
+
} else {
|
|
812
|
+
setState({
|
|
813
|
+
// TODO: Address this error
|
|
814
|
+
//
|
|
815
|
+
// @ts-expect-error - Passing a string to something that expects a
|
|
816
|
+
// number.
|
|
817
|
+
valueUpper: value,
|
|
818
|
+
isValidUpper: true
|
|
785
819
|
});
|
|
786
820
|
}
|
|
821
|
+
};
|
|
822
|
+
const isValidValueForPosition = ({
|
|
823
|
+
handle,
|
|
824
|
+
value: newValue,
|
|
825
|
+
min,
|
|
826
|
+
max
|
|
827
|
+
}) => {
|
|
828
|
+
const {
|
|
829
|
+
value,
|
|
830
|
+
valueUpper
|
|
831
|
+
} = state;
|
|
832
|
+
if (!isValidValue({
|
|
833
|
+
value: newValue,
|
|
834
|
+
min,
|
|
835
|
+
max
|
|
836
|
+
})) {
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
if (handle === HandlePosition.LOWER) {
|
|
840
|
+
return !valueUpper || newValue <= valueUpper;
|
|
841
|
+
} else if (handle === HandlePosition.UPPER) {
|
|
842
|
+
return !value || newValue >= value;
|
|
843
|
+
}
|
|
844
|
+
return false;
|
|
845
|
+
};
|
|
846
|
+
const isValidValue = ({
|
|
847
|
+
value,
|
|
848
|
+
min,
|
|
849
|
+
max
|
|
850
|
+
}) => {
|
|
851
|
+
return !(value < min || value > max);
|
|
852
|
+
};
|
|
853
|
+
const getAdjustedValueForPosition = ({
|
|
854
|
+
handle,
|
|
855
|
+
value: newValueInput,
|
|
856
|
+
min,
|
|
857
|
+
max
|
|
858
|
+
}) => {
|
|
859
|
+
const {
|
|
860
|
+
value,
|
|
861
|
+
valueUpper
|
|
862
|
+
} = state;
|
|
863
|
+
let newValue = getAdjustedValue({
|
|
864
|
+
value: newValueInput,
|
|
865
|
+
min,
|
|
866
|
+
max
|
|
867
|
+
});
|
|
787
868
|
|
|
788
|
-
//
|
|
789
|
-
//
|
|
790
|
-
if (
|
|
791
|
-
|
|
869
|
+
// TODO: Just return the value.
|
|
870
|
+
// Next adjust to the opposite handle.
|
|
871
|
+
if (handle === HandlePosition.LOWER && valueUpper) {
|
|
872
|
+
newValue = newValue > valueUpper ? valueUpper : newValue;
|
|
873
|
+
} else if (handle === HandlePosition.UPPER && value) {
|
|
874
|
+
newValue = newValue < value ? value : newValue;
|
|
792
875
|
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
useRawValue: true
|
|
804
|
-
});
|
|
805
|
-
this.setState({
|
|
806
|
-
valueUpper,
|
|
807
|
-
leftUpper
|
|
808
|
-
});
|
|
809
|
-
} else {
|
|
810
|
-
this.setState({
|
|
811
|
-
valueUpper: undefined,
|
|
812
|
-
leftUpper: undefined
|
|
813
|
-
});
|
|
876
|
+
return newValue;
|
|
877
|
+
};
|
|
878
|
+
const getAdjustedValue = ({
|
|
879
|
+
value,
|
|
880
|
+
min,
|
|
881
|
+
max
|
|
882
|
+
}) => {
|
|
883
|
+
// TODO: Just return the value.
|
|
884
|
+
if (value < min) {
|
|
885
|
+
value = min;
|
|
814
886
|
}
|
|
815
|
-
|
|
887
|
+
if (value > max) {
|
|
888
|
+
value = max;
|
|
889
|
+
}
|
|
890
|
+
return value;
|
|
891
|
+
};
|
|
816
892
|
|
|
817
893
|
/**
|
|
818
|
-
*
|
|
819
|
-
* prop.
|
|
894
|
+
* Get the bounding rect for the requested handles' DOM element.
|
|
820
895
|
*
|
|
821
|
-
*
|
|
822
|
-
* @returns The value rounded to the precision determined by the step.
|
|
896
|
+
* If the bounding rect is not available, a new, empty DOMRect is returned.
|
|
823
897
|
*/
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
898
|
+
const getHandleBoundingRect = handle => {
|
|
899
|
+
let boundingRect;
|
|
900
|
+
if (handle === HandlePosition.LOWER) {
|
|
901
|
+
boundingRect = thumbRef.current?.getBoundingClientRect();
|
|
902
|
+
} else {
|
|
903
|
+
boundingRect = thumbRefUpper.current?.getBoundingClientRect();
|
|
904
|
+
}
|
|
905
|
+
return boundingRect ?? new DOMRect();
|
|
906
|
+
};
|
|
907
|
+
const getClientXFromEvent = event => {
|
|
829
908
|
let clientX;
|
|
830
909
|
if ('clientX' in event) {
|
|
831
910
|
clientX = event.clientX;
|
|
@@ -833,17 +912,12 @@ class Slider extends React.PureComponent {
|
|
|
833
912
|
clientX = event.touches[0].clientX;
|
|
834
913
|
}
|
|
835
914
|
return clientX;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
return typeof this.state.valueUpper !== 'undefined';
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
// syncs invalid state and prop
|
|
842
|
-
static getDerivedStateFromProps(props, state) {
|
|
915
|
+
};
|
|
916
|
+
React.useEffect(() => {
|
|
843
917
|
const {
|
|
844
918
|
isValid,
|
|
845
919
|
isValidUpper
|
|
846
|
-
} =
|
|
920
|
+
} = stateRef.current;
|
|
847
921
|
const derivedState = {};
|
|
848
922
|
|
|
849
923
|
// Will override state in favor of invalid prop
|
|
@@ -854,16 +928,20 @@ class Slider extends React.PureComponent {
|
|
|
854
928
|
if (isValid === false) derivedState.isValid = true;
|
|
855
929
|
if (isValidUpper === false) derivedState.isValidUpper = true;
|
|
856
930
|
}
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
931
|
+
if (Object.keys(derivedState).length) {
|
|
932
|
+
setState(derivedState);
|
|
933
|
+
}
|
|
934
|
+
}, [props.invalid]);
|
|
935
|
+
|
|
936
|
+
// TODO: Delete this IIFE. It was added to maintain whitespace and to make it clear
|
|
937
|
+
// what exactly has changed.
|
|
938
|
+
return ((_Fragment, _Fragment2, _Fragment3, _Fragment4) => {
|
|
861
939
|
const {
|
|
862
940
|
ariaLabelInput,
|
|
863
941
|
unstable_ariaLabelInputUpper: ariaLabelInputUpper,
|
|
864
942
|
className,
|
|
865
943
|
hideTextInput = false,
|
|
866
|
-
id =
|
|
944
|
+
id = inputIdRef.current = inputIdRef.current ||
|
|
867
945
|
// TODO:
|
|
868
946
|
// 1. Why isn't `inputId` just set to this value instead of an empty
|
|
869
947
|
// string?
|
|
@@ -893,8 +971,7 @@ class Slider extends React.PureComponent {
|
|
|
893
971
|
warnText,
|
|
894
972
|
translateWithId: t = translateWithId,
|
|
895
973
|
...other
|
|
896
|
-
} =
|
|
897
|
-
const twoHandles = this.hasTwoHandles();
|
|
974
|
+
} = props;
|
|
898
975
|
delete other.onRelease;
|
|
899
976
|
delete other.invalid;
|
|
900
977
|
delete other.unstable_valueUpper;
|
|
@@ -906,7 +983,7 @@ class Slider extends React.PureComponent {
|
|
|
906
983
|
correctedValue,
|
|
907
984
|
correctedPosition,
|
|
908
985
|
isRtl
|
|
909
|
-
} =
|
|
986
|
+
} = state;
|
|
910
987
|
const showWarning = !readOnly && warn ||
|
|
911
988
|
// TODO: https://github.com/carbon-design-system/carbon/issues/18991#issuecomment-2795709637
|
|
912
989
|
// eslint-disable-next-line valid-typeof , no-constant-binary-expression -- https://github.com/carbon-design-system/carbon/issues/20071
|
|
@@ -965,12 +1042,12 @@ class Slider extends React.PureComponent {
|
|
|
965
1042
|
}]);
|
|
966
1043
|
const lowerThumbWrapperProps = {
|
|
967
1044
|
style: {
|
|
968
|
-
insetInlineStart: `${
|
|
1045
|
+
insetInlineStart: `${state.left}%`
|
|
969
1046
|
}
|
|
970
1047
|
};
|
|
971
1048
|
const upperThumbWrapperProps = {
|
|
972
1049
|
style: {
|
|
973
|
-
insetInlineStart: `${
|
|
1050
|
+
insetInlineStart: `${state.leftUpper}%`
|
|
974
1051
|
}
|
|
975
1052
|
};
|
|
976
1053
|
return /*#__PURE__*/React.createElement("div", {
|
|
@@ -996,10 +1073,10 @@ class Slider extends React.PureComponent {
|
|
|
996
1073
|
min: min,
|
|
997
1074
|
max: max,
|
|
998
1075
|
step: step,
|
|
999
|
-
onChange:
|
|
1000
|
-
onBlur:
|
|
1001
|
-
onKeyUp:
|
|
1002
|
-
onKeyDown:
|
|
1076
|
+
onChange: onChangeInput,
|
|
1077
|
+
onBlur: onBlurInput,
|
|
1078
|
+
onKeyUp: props.onInputKeyUp,
|
|
1079
|
+
onKeyDown: onInputKeyDown,
|
|
1003
1080
|
"data-invalid": !isValid && !readOnly ? true : null,
|
|
1004
1081
|
"data-handle-position": HandlePosition.LOWER,
|
|
1005
1082
|
"aria-invalid": !isValid && !readOnly ? true : undefined,
|
|
@@ -1013,11 +1090,11 @@ class Slider extends React.PureComponent {
|
|
|
1013
1090
|
}, formatLabel(min, minLabel)), /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
|
|
1014
1091
|
className: sliderClasses,
|
|
1015
1092
|
ref: node => {
|
|
1016
|
-
|
|
1093
|
+
elementRef.current = node;
|
|
1017
1094
|
},
|
|
1018
|
-
onMouseDown:
|
|
1019
|
-
onTouchStart:
|
|
1020
|
-
onKeyDown:
|
|
1095
|
+
onMouseDown: onDragStart,
|
|
1096
|
+
onTouchStart: onDragStart,
|
|
1097
|
+
onKeyDown: onKeyDown,
|
|
1021
1098
|
role: "presentation",
|
|
1022
1099
|
tabIndex: -1,
|
|
1023
1100
|
"data-invalid": (twoHandles ? !isValid || !isValidUpper : !isValid) && !readOnly ? true : null
|
|
@@ -1037,8 +1114,8 @@ class Slider extends React.PureComponent {
|
|
|
1037
1114
|
"aria-valuenow": value,
|
|
1038
1115
|
"aria-labelledby": twoHandles ? undefined : labelId,
|
|
1039
1116
|
"aria-label": twoHandles ? ariaLabelInput : undefined,
|
|
1040
|
-
ref:
|
|
1041
|
-
onFocus: () =>
|
|
1117
|
+
ref: thumbRef,
|
|
1118
|
+
onFocus: () => setState({
|
|
1042
1119
|
activeHandle: HandlePosition.LOWER
|
|
1043
1120
|
})
|
|
1044
1121
|
}, twoHandles && !isRtl ? _Fragment || (_Fragment = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SliderHandles.LowerHandle, {
|
|
@@ -1062,8 +1139,8 @@ class Slider extends React.PureComponent {
|
|
|
1062
1139
|
"aria-valuemin": value,
|
|
1063
1140
|
"aria-valuenow": valueUpper,
|
|
1064
1141
|
"aria-label": ariaLabelInputUpper,
|
|
1065
|
-
ref:
|
|
1066
|
-
onFocus: () =>
|
|
1142
|
+
ref: thumbRefUpper,
|
|
1143
|
+
onFocus: () => setState({
|
|
1067
1144
|
activeHandle: HandlePosition.UPPER
|
|
1068
1145
|
})
|
|
1069
1146
|
}, twoHandles && !isRtl ? _Fragment3 || (_Fragment3 = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SliderHandles.UpperHandle, {
|
|
@@ -1077,11 +1154,11 @@ class Slider extends React.PureComponent {
|
|
|
1077
1154
|
}))) : undefined)) : null, /*#__PURE__*/React.createElement("div", {
|
|
1078
1155
|
className: `${prefix}--slider__track`,
|
|
1079
1156
|
ref: node => {
|
|
1080
|
-
|
|
1157
|
+
trackRef.current = node;
|
|
1081
1158
|
}
|
|
1082
1159
|
}), /*#__PURE__*/React.createElement("div", {
|
|
1083
1160
|
className: `${prefix}--slider__filled-track`,
|
|
1084
|
-
ref:
|
|
1161
|
+
ref: filledTrackRef
|
|
1085
1162
|
})), /*#__PURE__*/React.createElement(Text.Text, {
|
|
1086
1163
|
className: `${prefix}--slider__range-label`
|
|
1087
1164
|
}, formatLabel(max, maxLabel)), /*#__PURE__*/React.createElement("div", {
|
|
@@ -1099,10 +1176,10 @@ class Slider extends React.PureComponent {
|
|
|
1099
1176
|
min: min,
|
|
1100
1177
|
max: max,
|
|
1101
1178
|
step: step,
|
|
1102
|
-
onChange:
|
|
1103
|
-
onBlur:
|
|
1104
|
-
onKeyDown:
|
|
1105
|
-
onKeyUp:
|
|
1179
|
+
onChange: onChangeInput,
|
|
1180
|
+
onBlur: onBlurInput,
|
|
1181
|
+
onKeyDown: onInputKeyDown,
|
|
1182
|
+
onKeyUp: props.onInputKeyUp,
|
|
1106
1183
|
"data-invalid": (twoHandles ? !isValidUpper : !isValid) && !readOnly ? true : null,
|
|
1107
1184
|
"data-handle-position": twoHandles ? HandlePosition.UPPER : null,
|
|
1108
1185
|
"aria-invalid": (twoHandles ? !isValidUpper : !isValid) && !readOnly ? true : undefined,
|
|
@@ -1125,10 +1202,8 @@ class Slider extends React.PureComponent {
|
|
|
1125
1202
|
correctedValue
|
|
1126
1203
|
})));
|
|
1127
1204
|
});
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
_rollupPluginBabelHelpers.defineProperty(Slider, "contextType", index.FeatureFlagContext);
|
|
1131
|
-
_rollupPluginBabelHelpers.defineProperty(Slider, "translationIds", Object.values(translationIds));
|
|
1205
|
+
})();
|
|
1206
|
+
};
|
|
1132
1207
|
Slider.propTypes = {
|
|
1133
1208
|
/**
|
|
1134
1209
|
* The `ariaLabel` for the `<input>`.
|
|
@@ -1269,4 +1344,4 @@ Slider.propTypes = {
|
|
|
1269
1344
|
warnText: PropTypes.node
|
|
1270
1345
|
};
|
|
1271
1346
|
|
|
1272
|
-
exports.
|
|
1347
|
+
exports.Slider = Slider;
|