@mui/material 6.0.0-beta.0 → 6.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/Autocomplete/Autocomplete.d.ts +6 -7
  2. package/Autocomplete/Autocomplete.js +1 -1
  3. package/Badge/Badge.d.ts +1 -1
  4. package/Badge/Badge.js +2 -2
  5. package/Badge/useBadge.d.ts +13 -0
  6. package/Badge/useBadge.js +41 -0
  7. package/Badge/useBadge.types.d.ts +40 -0
  8. package/Badge/useBadge.types.js +1 -0
  9. package/Breadcrumbs/Breadcrumbs.d.ts +1 -1
  10. package/Breadcrumbs/Breadcrumbs.js +1 -1
  11. package/CHANGELOG.md +32 -0
  12. package/ClickAwayListener/ClickAwayListener.d.ts +47 -0
  13. package/ClickAwayListener/ClickAwayListener.js +178 -0
  14. package/ClickAwayListener/index.d.ts +2 -2
  15. package/ClickAwayListener/index.js +1 -1
  16. package/InputBase/InputBase.js +2 -2
  17. package/ListItem/ListItem.js +1 -1
  18. package/Menu/Menu.js +1 -1
  19. package/Modal/Modal.d.ts +1 -1
  20. package/Modal/Modal.js +1 -1
  21. package/Modal/ModalManager.d.ts +25 -0
  22. package/Modal/ModalManager.js +211 -0
  23. package/Modal/index.d.ts +1 -1
  24. package/Modal/index.js +1 -1
  25. package/Modal/useModal.d.ts +13 -0
  26. package/Modal/useModal.js +195 -0
  27. package/Modal/useModal.types.d.ts +115 -0
  28. package/Modal/useModal.types.js +1 -0
  29. package/NoSsr/NoSsr.d.ts +25 -0
  30. package/NoSsr/NoSsr.js +73 -0
  31. package/NoSsr/NoSsr.types.d.ts +18 -0
  32. package/NoSsr/NoSsr.types.js +1 -0
  33. package/NoSsr/index.d.ts +3 -2
  34. package/NoSsr/index.js +1 -1
  35. package/Popover/Popover.js +1 -1
  36. package/Popper/BasePopper.d.ts +7 -0
  37. package/Popper/BasePopper.js +370 -0
  38. package/Popper/BasePopper.types.d.ts +130 -0
  39. package/Popper/BasePopper.types.js +1 -0
  40. package/Popper/Popper.d.ts +1 -1
  41. package/Popper/Popper.js +1 -1
  42. package/Popper/index.d.ts +2 -1
  43. package/Popper/index.js +2 -1
  44. package/Popper/popperClasses.d.ts +8 -0
  45. package/Popper/popperClasses.js +7 -0
  46. package/Portal/Portal.d.ts +16 -0
  47. package/Portal/Portal.js +92 -0
  48. package/Portal/Portal.types.d.ts +23 -0
  49. package/Portal/Portal.types.js +1 -0
  50. package/Portal/index.d.ts +3 -2
  51. package/Portal/index.js +1 -1
  52. package/Slider/Slider.d.ts +2 -2
  53. package/Slider/Slider.js +3 -2
  54. package/Slider/useSlider.d.ts +14 -0
  55. package/Slider/useSlider.js +647 -0
  56. package/Slider/useSlider.types.d.ts +228 -0
  57. package/Slider/useSlider.types.js +1 -0
  58. package/Snackbar/Snackbar.d.ts +1 -1
  59. package/Snackbar/Snackbar.js +3 -3
  60. package/Snackbar/useSnackbar.d.ts +14 -0
  61. package/Snackbar/useSnackbar.js +133 -0
  62. package/Snackbar/useSnackbar.types.d.ts +60 -0
  63. package/Snackbar/useSnackbar.types.js +1 -0
  64. package/SwipeableDrawer/SwipeableDrawer.js +1 -1
  65. package/TabScrollButton/TabScrollButton.d.ts +1 -1
  66. package/TabScrollButton/TabScrollButton.js +1 -1
  67. package/TablePagination/TablePagination.js +1 -1
  68. package/Tabs/Tabs.d.ts +1 -1
  69. package/Tabs/Tabs.js +1 -1
  70. package/TextareaAutosize/TextareaAutosize.d.ts +14 -0
  71. package/TextareaAutosize/TextareaAutosize.js +222 -0
  72. package/TextareaAutosize/TextareaAutosize.types.d.ts +13 -0
  73. package/TextareaAutosize/TextareaAutosize.types.js +1 -0
  74. package/TextareaAutosize/index.d.ts +3 -2
  75. package/TextareaAutosize/index.js +1 -1
  76. package/Tooltip/Tooltip.js +1 -1
  77. package/Unstable_TrapFocus/FocusTrap.d.ts +10 -0
  78. package/Unstable_TrapFocus/FocusTrap.js +330 -0
  79. package/Unstable_TrapFocus/FocusTrap.types.d.ts +51 -0
  80. package/Unstable_TrapFocus/FocusTrap.types.js +1 -0
  81. package/Unstable_TrapFocus/index.d.ts +2 -2
  82. package/Unstable_TrapFocus/index.js +1 -1
  83. package/index.d.ts +1 -1
  84. package/index.js +2 -2
  85. package/modern/Autocomplete/Autocomplete.js +1 -1
  86. package/modern/Badge/Badge.js +2 -2
  87. package/modern/Badge/useBadge.js +41 -0
  88. package/modern/Badge/useBadge.types.js +1 -0
  89. package/modern/Breadcrumbs/Breadcrumbs.js +1 -1
  90. package/modern/ClickAwayListener/ClickAwayListener.js +178 -0
  91. package/modern/ClickAwayListener/index.js +1 -1
  92. package/modern/InputBase/InputBase.js +2 -2
  93. package/modern/ListItem/ListItem.js +1 -1
  94. package/modern/Menu/Menu.js +1 -1
  95. package/modern/Modal/Modal.js +1 -1
  96. package/modern/Modal/ModalManager.js +211 -0
  97. package/modern/Modal/index.js +1 -1
  98. package/modern/Modal/useModal.js +195 -0
  99. package/modern/Modal/useModal.types.js +1 -0
  100. package/modern/NoSsr/NoSsr.js +73 -0
  101. package/modern/NoSsr/NoSsr.types.js +1 -0
  102. package/modern/NoSsr/index.js +1 -1
  103. package/modern/Popover/Popover.js +1 -1
  104. package/modern/Popper/BasePopper.js +370 -0
  105. package/modern/Popper/BasePopper.types.js +1 -0
  106. package/modern/Popper/Popper.js +1 -1
  107. package/modern/Popper/index.js +2 -1
  108. package/modern/Popper/popperClasses.js +7 -0
  109. package/modern/Portal/Portal.js +92 -0
  110. package/modern/Portal/Portal.types.js +1 -0
  111. package/modern/Portal/index.js +1 -1
  112. package/modern/Slider/Slider.js +3 -2
  113. package/modern/Slider/useSlider.js +647 -0
  114. package/modern/Slider/useSlider.types.js +1 -0
  115. package/modern/Snackbar/Snackbar.js +3 -3
  116. package/modern/Snackbar/useSnackbar.js +133 -0
  117. package/modern/Snackbar/useSnackbar.types.js +1 -0
  118. package/modern/SwipeableDrawer/SwipeableDrawer.js +1 -1
  119. package/modern/TabScrollButton/TabScrollButton.js +1 -1
  120. package/modern/TablePagination/TablePagination.js +1 -1
  121. package/modern/Tabs/Tabs.js +1 -1
  122. package/modern/TextareaAutosize/TextareaAutosize.js +222 -0
  123. package/modern/TextareaAutosize/TextareaAutosize.types.js +1 -0
  124. package/modern/TextareaAutosize/index.js +1 -1
  125. package/modern/Tooltip/Tooltip.js +1 -1
  126. package/modern/Unstable_TrapFocus/FocusTrap.js +330 -0
  127. package/modern/Unstable_TrapFocus/FocusTrap.types.js +1 -0
  128. package/modern/Unstable_TrapFocus/index.js +1 -1
  129. package/modern/index.js +2 -2
  130. package/modern/useAutocomplete/useAutocomplete.js +976 -2
  131. package/modern/utils/PolymorphicComponent.js +1 -0
  132. package/modern/utils/areArraysEqual.js +4 -0
  133. package/modern/utils/index.js +1 -1
  134. package/modern/utils/isHostComponent.js +7 -0
  135. package/modern/utils/omitEventHandlers.js +18 -0
  136. package/modern/utils/shouldSpreadAdditionalProps.js +1 -1
  137. package/modern/utils/useSlot.js +3 -1
  138. package/node/Autocomplete/Autocomplete.js +3 -3
  139. package/node/Badge/Badge.js +5 -5
  140. package/node/Badge/useBadge.js +46 -0
  141. package/node/Badge/useBadge.types.js +5 -0
  142. package/node/Breadcrumbs/Breadcrumbs.js +2 -2
  143. package/node/ClickAwayListener/ClickAwayListener.js +184 -0
  144. package/node/ClickAwayListener/index.js +1 -1
  145. package/node/InputBase/InputBase.js +7 -7
  146. package/node/ListItem/ListItem.js +3 -3
  147. package/node/Menu/Menu.js +3 -3
  148. package/node/Modal/Modal.js +2 -2
  149. package/node/Modal/ModalManager.js +219 -0
  150. package/node/Modal/index.js +2 -2
  151. package/node/Modal/useModal.js +205 -0
  152. package/node/Modal/useModal.types.js +5 -0
  153. package/node/NoSsr/NoSsr.js +81 -0
  154. package/node/NoSsr/NoSsr.types.js +5 -0
  155. package/node/NoSsr/index.js +3 -2
  156. package/node/Popover/Popover.js +2 -2
  157. package/node/Popper/BasePopper.js +379 -0
  158. package/node/Popper/BasePopper.types.js +5 -0
  159. package/node/Popper/Popper.js +2 -2
  160. package/node/Popper/index.js +14 -1
  161. package/node/Popper/popperClasses.js +15 -0
  162. package/node/Portal/Portal.js +100 -0
  163. package/node/Portal/Portal.types.js +5 -0
  164. package/node/Portal/index.js +3 -2
  165. package/node/Slider/Slider.js +14 -13
  166. package/node/Slider/useSlider.js +670 -0
  167. package/node/Slider/useSlider.types.js +5 -0
  168. package/node/Snackbar/Snackbar.js +6 -6
  169. package/node/Snackbar/useSnackbar.js +141 -0
  170. package/node/Snackbar/useSnackbar.types.js +5 -0
  171. package/node/SwipeableDrawer/SwipeableDrawer.js +2 -2
  172. package/node/TabScrollButton/TabScrollButton.js +3 -3
  173. package/node/TablePagination/TablePagination.js +2 -2
  174. package/node/Tabs/Tabs.js +3 -3
  175. package/node/TextareaAutosize/TextareaAutosize.js +230 -0
  176. package/node/TextareaAutosize/TextareaAutosize.types.js +5 -0
  177. package/node/TextareaAutosize/index.js +3 -2
  178. package/node/Tooltip/Tooltip.js +5 -5
  179. package/node/Unstable_TrapFocus/FocusTrap.js +339 -0
  180. package/node/Unstable_TrapFocus/FocusTrap.types.js +5 -0
  181. package/node/Unstable_TrapFocus/index.js +3 -2
  182. package/node/index.js +3 -3
  183. package/node/useAutocomplete/useAutocomplete.js +985 -18
  184. package/node/utils/PolymorphicComponent.js +5 -0
  185. package/node/utils/areArraysEqual.js +10 -0
  186. package/node/utils/index.js +2 -2
  187. package/node/utils/isHostComponent.js +13 -0
  188. package/node/utils/omitEventHandlers.js +24 -0
  189. package/node/utils/shouldSpreadAdditionalProps.js +3 -2
  190. package/node/utils/useSlot.js +6 -4
  191. package/package.json +6 -7
  192. package/styles/overrides.d.ts +1 -1
  193. package/useAutocomplete/useAutocomplete.d.ts +468 -2
  194. package/useAutocomplete/useAutocomplete.js +976 -2
  195. package/utils/PolymorphicComponent.d.ts +17 -0
  196. package/utils/PolymorphicComponent.js +1 -0
  197. package/utils/areArraysEqual.d.ts +3 -0
  198. package/utils/areArraysEqual.js +4 -0
  199. package/utils/index.d.ts +2 -1
  200. package/utils/index.js +1 -1
  201. package/utils/isHostComponent.d.ts +6 -0
  202. package/utils/isHostComponent.js +7 -0
  203. package/utils/omitEventHandlers.d.ts +9 -0
  204. package/utils/omitEventHandlers.js +18 -0
  205. package/utils/shouldSpreadAdditionalProps.js +1 -1
  206. package/utils/types.d.ts +2 -1
  207. package/utils/useSlot.js +3 -1
@@ -0,0 +1,647 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { unstable_ownerDocument as ownerDocument, unstable_useControlled as useControlled, unstable_useEnhancedEffect as useEnhancedEffect, unstable_useEventCallback as useEventCallback, unstable_useForkRef as useForkRef, unstable_isFocusVisible as isFocusVisible, visuallyHidden, clamp } from '@mui/utils';
5
+ import extractEventHandlers from '@mui/utils/extractEventHandlers';
6
+ import areArraysEqual from '../utils/areArraysEqual';
7
+ const INTENTIONAL_DRAG_COUNT_THRESHOLD = 2;
8
+ function asc(a, b) {
9
+ return a - b;
10
+ }
11
+ function findClosest(values, currentValue) {
12
+ const {
13
+ index: closestIndex
14
+ } = values.reduce((acc, value, index) => {
15
+ const distance = Math.abs(currentValue - value);
16
+ if (acc === null || distance < acc.distance || distance === acc.distance) {
17
+ return {
18
+ distance,
19
+ index
20
+ };
21
+ }
22
+ return acc;
23
+ }, null) ?? {};
24
+ return closestIndex;
25
+ }
26
+ function trackFinger(event, touchId) {
27
+ // The event is TouchEvent
28
+ if (touchId.current !== undefined && event.changedTouches) {
29
+ const touchEvent = event;
30
+ for (let i = 0; i < touchEvent.changedTouches.length; i += 1) {
31
+ const touch = touchEvent.changedTouches[i];
32
+ if (touch.identifier === touchId.current) {
33
+ return {
34
+ x: touch.clientX,
35
+ y: touch.clientY
36
+ };
37
+ }
38
+ }
39
+ return false;
40
+ }
41
+
42
+ // The event is MouseEvent
43
+ return {
44
+ x: event.clientX,
45
+ y: event.clientY
46
+ };
47
+ }
48
+ export function valueToPercent(value, min, max) {
49
+ return (value - min) * 100 / (max - min);
50
+ }
51
+ function percentToValue(percent, min, max) {
52
+ return (max - min) * percent + min;
53
+ }
54
+ function getDecimalPrecision(num) {
55
+ // This handles the case when num is very small (0.00000001), js will turn this into 1e-8.
56
+ // When num is bigger than 1 or less than -1 it won't get converted to this notation so it's fine.
57
+ if (Math.abs(num) < 1) {
58
+ const parts = num.toExponential().split('e-');
59
+ const matissaDecimalPart = parts[0].split('.')[1];
60
+ return (matissaDecimalPart ? matissaDecimalPart.length : 0) + parseInt(parts[1], 10);
61
+ }
62
+ const decimalPart = num.toString().split('.')[1];
63
+ return decimalPart ? decimalPart.length : 0;
64
+ }
65
+ function roundValueToStep(value, step, min) {
66
+ const nearest = Math.round((value - min) / step) * step + min;
67
+ return Number(nearest.toFixed(getDecimalPrecision(step)));
68
+ }
69
+ function setValueIndex({
70
+ values,
71
+ newValue,
72
+ index
73
+ }) {
74
+ const output = values.slice();
75
+ output[index] = newValue;
76
+ return output.sort(asc);
77
+ }
78
+ function focusThumb({
79
+ sliderRef,
80
+ activeIndex,
81
+ setActive
82
+ }) {
83
+ const doc = ownerDocument(sliderRef.current);
84
+ if (!sliderRef.current?.contains(doc.activeElement) || Number(doc?.activeElement?.getAttribute('data-index')) !== activeIndex) {
85
+ sliderRef.current?.querySelector(`[type="range"][data-index="${activeIndex}"]`).focus();
86
+ }
87
+ if (setActive) {
88
+ setActive(activeIndex);
89
+ }
90
+ }
91
+ function areValuesEqual(newValue, oldValue) {
92
+ if (typeof newValue === 'number' && typeof oldValue === 'number') {
93
+ return newValue === oldValue;
94
+ }
95
+ if (typeof newValue === 'object' && typeof oldValue === 'object') {
96
+ return areArraysEqual(newValue, oldValue);
97
+ }
98
+ return false;
99
+ }
100
+ const axisProps = {
101
+ horizontal: {
102
+ offset: percent => ({
103
+ left: `${percent}%`
104
+ }),
105
+ leap: percent => ({
106
+ width: `${percent}%`
107
+ })
108
+ },
109
+ 'horizontal-reverse': {
110
+ offset: percent => ({
111
+ right: `${percent}%`
112
+ }),
113
+ leap: percent => ({
114
+ width: `${percent}%`
115
+ })
116
+ },
117
+ vertical: {
118
+ offset: percent => ({
119
+ bottom: `${percent}%`
120
+ }),
121
+ leap: percent => ({
122
+ height: `${percent}%`
123
+ })
124
+ }
125
+ };
126
+ export const Identity = x => x;
127
+
128
+ // TODO: remove support for Safari < 13.
129
+ // https://caniuse.com/#search=touch-action
130
+ //
131
+ // Safari, on iOS, supports touch action since v13.
132
+ // Over 80% of the iOS phones are compatible
133
+ // in August 2020.
134
+ // Utilizing the CSS.supports method to check if touch-action is supported.
135
+ // Since CSS.supports is supported on all but Edge@12 and IE and touch-action
136
+ // is supported on both Edge@12 and IE if CSS.supports is not available that means that
137
+ // touch-action will be supported
138
+ let cachedSupportsTouchActionNone;
139
+ function doesSupportTouchActionNone() {
140
+ if (cachedSupportsTouchActionNone === undefined) {
141
+ if (typeof CSS !== 'undefined' && typeof CSS.supports === 'function') {
142
+ cachedSupportsTouchActionNone = CSS.supports('touch-action', 'none');
143
+ } else {
144
+ cachedSupportsTouchActionNone = true;
145
+ }
146
+ }
147
+ return cachedSupportsTouchActionNone;
148
+ }
149
+ /**
150
+ *
151
+ * Demos:
152
+ *
153
+ * - [Slider](https://next.mui.com/base-ui/react-slider/#hook)
154
+ *
155
+ * API:
156
+ *
157
+ * - [useSlider API](https://next.mui.com/base-ui/react-slider/hooks-api/#use-slider)
158
+ */
159
+ export function useSlider(parameters) {
160
+ const {
161
+ 'aria-labelledby': ariaLabelledby,
162
+ defaultValue,
163
+ disabled = false,
164
+ disableSwap = false,
165
+ isRtl = false,
166
+ marks: marksProp = false,
167
+ max = 100,
168
+ min = 0,
169
+ name,
170
+ onChange,
171
+ onChangeCommitted,
172
+ orientation = 'horizontal',
173
+ rootRef: ref,
174
+ scale = Identity,
175
+ step = 1,
176
+ shiftStep = 10,
177
+ tabIndex,
178
+ value: valueProp
179
+ } = parameters;
180
+ const touchId = React.useRef();
181
+ // We can't use the :active browser pseudo-classes.
182
+ // - The active state isn't triggered when clicking on the rail.
183
+ // - The active state isn't transferred when inversing a range slider.
184
+ const [active, setActive] = React.useState(-1);
185
+ const [open, setOpen] = React.useState(-1);
186
+ const [dragging, setDragging] = React.useState(false);
187
+ const moveCount = React.useRef(0);
188
+ const [valueDerived, setValueState] = useControlled({
189
+ controlled: valueProp,
190
+ default: defaultValue ?? min,
191
+ name: 'Slider'
192
+ });
193
+ const handleChange = onChange && ((event, value, thumbIndex) => {
194
+ // Redefine target to allow name and value to be read.
195
+ // This allows seamless integration with the most popular form libraries.
196
+ // https://github.com/mui/material-ui/issues/13485#issuecomment-676048492
197
+ // Clone the event to not override `target` of the original event.
198
+ const nativeEvent = event.nativeEvent || event;
199
+ // @ts-ignore The nativeEvent is function, not object
200
+ const clonedEvent = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
201
+ Object.defineProperty(clonedEvent, 'target', {
202
+ writable: true,
203
+ value: {
204
+ value,
205
+ name
206
+ }
207
+ });
208
+ onChange(clonedEvent, value, thumbIndex);
209
+ });
210
+ const range = Array.isArray(valueDerived);
211
+ let values = range ? valueDerived.slice().sort(asc) : [valueDerived];
212
+ values = values.map(value => value == null ? min : clamp(value, min, max));
213
+ const marks = marksProp === true && step !== null ? [...Array(Math.floor((max - min) / step) + 1)].map((_, index) => ({
214
+ value: min + step * index
215
+ })) : marksProp || [];
216
+ const marksValues = marks.map(mark => mark.value);
217
+ const [focusedThumbIndex, setFocusedThumbIndex] = React.useState(-1);
218
+ const sliderRef = React.useRef();
219
+ const handleRef = useForkRef(ref, sliderRef);
220
+ const createHandleHiddenInputFocus = otherHandlers => event => {
221
+ const index = Number(event.currentTarget.getAttribute('data-index'));
222
+ if (isFocusVisible(event.target)) {
223
+ setFocusedThumbIndex(index);
224
+ }
225
+ setOpen(index);
226
+ otherHandlers?.onFocus?.(event);
227
+ };
228
+ const createHandleHiddenInputBlur = otherHandlers => event => {
229
+ if (!isFocusVisible(event.target)) {
230
+ setFocusedThumbIndex(-1);
231
+ }
232
+ setOpen(-1);
233
+ otherHandlers?.onBlur?.(event);
234
+ };
235
+ const changeValue = (event, valueInput) => {
236
+ const index = Number(event.currentTarget.getAttribute('data-index'));
237
+ const value = values[index];
238
+ const marksIndex = marksValues.indexOf(value);
239
+ let newValue = valueInput;
240
+ if (marks && step == null) {
241
+ const maxMarksValue = marksValues[marksValues.length - 1];
242
+ if (newValue > maxMarksValue) {
243
+ newValue = maxMarksValue;
244
+ } else if (newValue < marksValues[0]) {
245
+ newValue = marksValues[0];
246
+ } else {
247
+ newValue = newValue < value ? marksValues[marksIndex - 1] : marksValues[marksIndex + 1];
248
+ }
249
+ }
250
+ newValue = clamp(newValue, min, max);
251
+ if (range) {
252
+ // Bound the new value to the thumb's neighbours.
253
+ if (disableSwap) {
254
+ newValue = clamp(newValue, values[index - 1] || -Infinity, values[index + 1] || Infinity);
255
+ }
256
+ const previousValue = newValue;
257
+ newValue = setValueIndex({
258
+ values,
259
+ newValue,
260
+ index
261
+ });
262
+ let activeIndex = index;
263
+
264
+ // Potentially swap the index if needed.
265
+ if (!disableSwap) {
266
+ activeIndex = newValue.indexOf(previousValue);
267
+ }
268
+ focusThumb({
269
+ sliderRef,
270
+ activeIndex
271
+ });
272
+ }
273
+ setValueState(newValue);
274
+ setFocusedThumbIndex(index);
275
+ if (handleChange && !areValuesEqual(newValue, valueDerived)) {
276
+ handleChange(event, newValue, index);
277
+ }
278
+ if (onChangeCommitted) {
279
+ onChangeCommitted(event, newValue);
280
+ }
281
+ };
282
+ const createHandleHiddenInputKeyDown = otherHandlers => event => {
283
+ // The Shift + Up/Down keyboard shortcuts for moving the slider makes sense to be supported
284
+ // only if the step is defined. If the step is null, this means tha the marks are used for specifying the valid values.
285
+ if (step !== null) {
286
+ const index = Number(event.currentTarget.getAttribute('data-index'));
287
+ const value = values[index];
288
+ let newValue = null;
289
+ if ((event.key === 'ArrowLeft' || event.key === 'ArrowDown') && event.shiftKey || event.key === 'PageDown') {
290
+ newValue = Math.max(value - shiftStep, min);
291
+ } else if ((event.key === 'ArrowRight' || event.key === 'ArrowUp') && event.shiftKey || event.key === 'PageUp') {
292
+ newValue = Math.min(value + shiftStep, max);
293
+ }
294
+ if (newValue !== null) {
295
+ changeValue(event, newValue);
296
+ event.preventDefault();
297
+ }
298
+ }
299
+ otherHandlers?.onKeyDown?.(event);
300
+ };
301
+ useEnhancedEffect(() => {
302
+ if (disabled && sliderRef.current.contains(document.activeElement)) {
303
+ // This is necessary because Firefox and Safari will keep focus
304
+ // on a disabled element:
305
+ // https://codesandbox.io/p/sandbox/mui-pr-22247-forked-h151h?file=/src/App.js
306
+ // @ts-ignore
307
+ document.activeElement?.blur();
308
+ }
309
+ }, [disabled]);
310
+ if (disabled && active !== -1) {
311
+ setActive(-1);
312
+ }
313
+ if (disabled && focusedThumbIndex !== -1) {
314
+ setFocusedThumbIndex(-1);
315
+ }
316
+ const createHandleHiddenInputChange = otherHandlers => event => {
317
+ otherHandlers.onChange?.(event);
318
+ // @ts-ignore
319
+ changeValue(event, event.target.valueAsNumber);
320
+ };
321
+ const previousIndex = React.useRef();
322
+ let axis = orientation;
323
+ if (isRtl && orientation === 'horizontal') {
324
+ axis += '-reverse';
325
+ }
326
+ const getFingerNewValue = ({
327
+ finger,
328
+ move = false
329
+ }) => {
330
+ const {
331
+ current: slider
332
+ } = sliderRef;
333
+ const {
334
+ width,
335
+ height,
336
+ bottom,
337
+ left
338
+ } = slider.getBoundingClientRect();
339
+ let percent;
340
+ if (axis.indexOf('vertical') === 0) {
341
+ percent = (bottom - finger.y) / height;
342
+ } else {
343
+ percent = (finger.x - left) / width;
344
+ }
345
+ if (axis.indexOf('-reverse') !== -1) {
346
+ percent = 1 - percent;
347
+ }
348
+ let newValue;
349
+ newValue = percentToValue(percent, min, max);
350
+ if (step) {
351
+ newValue = roundValueToStep(newValue, step, min);
352
+ } else {
353
+ const closestIndex = findClosest(marksValues, newValue);
354
+ newValue = marksValues[closestIndex];
355
+ }
356
+ newValue = clamp(newValue, min, max);
357
+ let activeIndex = 0;
358
+ if (range) {
359
+ if (!move) {
360
+ activeIndex = findClosest(values, newValue);
361
+ } else {
362
+ activeIndex = previousIndex.current;
363
+ }
364
+
365
+ // Bound the new value to the thumb's neighbours.
366
+ if (disableSwap) {
367
+ newValue = clamp(newValue, values[activeIndex - 1] || -Infinity, values[activeIndex + 1] || Infinity);
368
+ }
369
+ const previousValue = newValue;
370
+ newValue = setValueIndex({
371
+ values,
372
+ newValue,
373
+ index: activeIndex
374
+ });
375
+
376
+ // Potentially swap the index if needed.
377
+ if (!(disableSwap && move)) {
378
+ activeIndex = newValue.indexOf(previousValue);
379
+ previousIndex.current = activeIndex;
380
+ }
381
+ }
382
+ return {
383
+ newValue,
384
+ activeIndex
385
+ };
386
+ };
387
+ const handleTouchMove = useEventCallback(nativeEvent => {
388
+ const finger = trackFinger(nativeEvent, touchId);
389
+ if (!finger) {
390
+ return;
391
+ }
392
+ moveCount.current += 1;
393
+
394
+ // Cancel move in case some other element consumed a mouseup event and it was not fired.
395
+ // @ts-ignore buttons doesn't not exists on touch event
396
+ if (nativeEvent.type === 'mousemove' && nativeEvent.buttons === 0) {
397
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
398
+ handleTouchEnd(nativeEvent);
399
+ return;
400
+ }
401
+ const {
402
+ newValue,
403
+ activeIndex
404
+ } = getFingerNewValue({
405
+ finger,
406
+ move: true
407
+ });
408
+ focusThumb({
409
+ sliderRef,
410
+ activeIndex,
411
+ setActive
412
+ });
413
+ setValueState(newValue);
414
+ if (!dragging && moveCount.current > INTENTIONAL_DRAG_COUNT_THRESHOLD) {
415
+ setDragging(true);
416
+ }
417
+ if (handleChange && !areValuesEqual(newValue, valueDerived)) {
418
+ handleChange(nativeEvent, newValue, activeIndex);
419
+ }
420
+ });
421
+ const handleTouchEnd = useEventCallback(nativeEvent => {
422
+ const finger = trackFinger(nativeEvent, touchId);
423
+ setDragging(false);
424
+ if (!finger) {
425
+ return;
426
+ }
427
+ const {
428
+ newValue
429
+ } = getFingerNewValue({
430
+ finger,
431
+ move: true
432
+ });
433
+ setActive(-1);
434
+ if (nativeEvent.type === 'touchend') {
435
+ setOpen(-1);
436
+ }
437
+ if (onChangeCommitted) {
438
+ onChangeCommitted(nativeEvent, newValue);
439
+ }
440
+ touchId.current = undefined;
441
+
442
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
443
+ stopListening();
444
+ });
445
+ const handleTouchStart = useEventCallback(nativeEvent => {
446
+ if (disabled) {
447
+ return;
448
+ }
449
+ // If touch-action: none; is not supported we need to prevent the scroll manually.
450
+ if (!doesSupportTouchActionNone()) {
451
+ nativeEvent.preventDefault();
452
+ }
453
+ const touch = nativeEvent.changedTouches[0];
454
+ if (touch != null) {
455
+ // A number that uniquely identifies the current finger in the touch session.
456
+ touchId.current = touch.identifier;
457
+ }
458
+ const finger = trackFinger(nativeEvent, touchId);
459
+ if (finger !== false) {
460
+ const {
461
+ newValue,
462
+ activeIndex
463
+ } = getFingerNewValue({
464
+ finger
465
+ });
466
+ focusThumb({
467
+ sliderRef,
468
+ activeIndex,
469
+ setActive
470
+ });
471
+ setValueState(newValue);
472
+ if (handleChange && !areValuesEqual(newValue, valueDerived)) {
473
+ handleChange(nativeEvent, newValue, activeIndex);
474
+ }
475
+ }
476
+ moveCount.current = 0;
477
+ const doc = ownerDocument(sliderRef.current);
478
+ doc.addEventListener('touchmove', handleTouchMove, {
479
+ passive: true
480
+ });
481
+ doc.addEventListener('touchend', handleTouchEnd, {
482
+ passive: true
483
+ });
484
+ });
485
+ const stopListening = React.useCallback(() => {
486
+ const doc = ownerDocument(sliderRef.current);
487
+ doc.removeEventListener('mousemove', handleTouchMove);
488
+ doc.removeEventListener('mouseup', handleTouchEnd);
489
+ doc.removeEventListener('touchmove', handleTouchMove);
490
+ doc.removeEventListener('touchend', handleTouchEnd);
491
+ }, [handleTouchEnd, handleTouchMove]);
492
+ React.useEffect(() => {
493
+ const {
494
+ current: slider
495
+ } = sliderRef;
496
+ slider.addEventListener('touchstart', handleTouchStart, {
497
+ passive: doesSupportTouchActionNone()
498
+ });
499
+ return () => {
500
+ slider.removeEventListener('touchstart', handleTouchStart);
501
+ stopListening();
502
+ };
503
+ }, [stopListening, handleTouchStart]);
504
+ React.useEffect(() => {
505
+ if (disabled) {
506
+ stopListening();
507
+ }
508
+ }, [disabled, stopListening]);
509
+ const createHandleMouseDown = otherHandlers => event => {
510
+ otherHandlers.onMouseDown?.(event);
511
+ if (disabled) {
512
+ return;
513
+ }
514
+ if (event.defaultPrevented) {
515
+ return;
516
+ }
517
+
518
+ // Only handle left clicks
519
+ if (event.button !== 0) {
520
+ return;
521
+ }
522
+
523
+ // Avoid text selection
524
+ event.preventDefault();
525
+ const finger = trackFinger(event, touchId);
526
+ if (finger !== false) {
527
+ const {
528
+ newValue,
529
+ activeIndex
530
+ } = getFingerNewValue({
531
+ finger
532
+ });
533
+ focusThumb({
534
+ sliderRef,
535
+ activeIndex,
536
+ setActive
537
+ });
538
+ setValueState(newValue);
539
+ if (handleChange && !areValuesEqual(newValue, valueDerived)) {
540
+ handleChange(event, newValue, activeIndex);
541
+ }
542
+ }
543
+ moveCount.current = 0;
544
+ const doc = ownerDocument(sliderRef.current);
545
+ doc.addEventListener('mousemove', handleTouchMove, {
546
+ passive: true
547
+ });
548
+ doc.addEventListener('mouseup', handleTouchEnd);
549
+ };
550
+ const trackOffset = valueToPercent(range ? values[0] : min, min, max);
551
+ const trackLeap = valueToPercent(values[values.length - 1], min, max) - trackOffset;
552
+ const getRootProps = (externalProps = {}) => {
553
+ const externalHandlers = extractEventHandlers(externalProps);
554
+ const ownEventHandlers = {
555
+ onMouseDown: createHandleMouseDown(externalHandlers || {})
556
+ };
557
+ const mergedEventHandlers = {
558
+ ...externalHandlers,
559
+ ...ownEventHandlers
560
+ };
561
+ return {
562
+ ...externalProps,
563
+ ref: handleRef,
564
+ ...mergedEventHandlers
565
+ };
566
+ };
567
+ const createHandleMouseOver = otherHandlers => event => {
568
+ otherHandlers.onMouseOver?.(event);
569
+ const index = Number(event.currentTarget.getAttribute('data-index'));
570
+ setOpen(index);
571
+ };
572
+ const createHandleMouseLeave = otherHandlers => event => {
573
+ otherHandlers.onMouseLeave?.(event);
574
+ setOpen(-1);
575
+ };
576
+ const getThumbProps = (externalProps = {}) => {
577
+ const externalHandlers = extractEventHandlers(externalProps);
578
+ const ownEventHandlers = {
579
+ onMouseOver: createHandleMouseOver(externalHandlers || {}),
580
+ onMouseLeave: createHandleMouseLeave(externalHandlers || {})
581
+ };
582
+ return {
583
+ ...externalProps,
584
+ ...externalHandlers,
585
+ ...ownEventHandlers
586
+ };
587
+ };
588
+ const getThumbStyle = index => {
589
+ return {
590
+ // So the non active thumb doesn't show its label on hover.
591
+ pointerEvents: active !== -1 && active !== index ? 'none' : undefined
592
+ };
593
+ };
594
+ const getHiddenInputProps = (externalProps = {}) => {
595
+ const externalHandlers = extractEventHandlers(externalProps);
596
+ const ownEventHandlers = {
597
+ onChange: createHandleHiddenInputChange(externalHandlers || {}),
598
+ onFocus: createHandleHiddenInputFocus(externalHandlers || {}),
599
+ onBlur: createHandleHiddenInputBlur(externalHandlers || {}),
600
+ onKeyDown: createHandleHiddenInputKeyDown(externalHandlers || {})
601
+ };
602
+ const mergedEventHandlers = {
603
+ ...externalHandlers,
604
+ ...ownEventHandlers
605
+ };
606
+ return {
607
+ tabIndex,
608
+ 'aria-labelledby': ariaLabelledby,
609
+ 'aria-orientation': orientation,
610
+ 'aria-valuemax': scale(max),
611
+ 'aria-valuemin': scale(min),
612
+ name,
613
+ type: 'range',
614
+ min: parameters.min,
615
+ max: parameters.max,
616
+ step: parameters.step === null && parameters.marks ? 'any' : parameters.step ?? undefined,
617
+ disabled,
618
+ ...externalProps,
619
+ ...mergedEventHandlers,
620
+ style: {
621
+ ...visuallyHidden,
622
+ direction: isRtl ? 'rtl' : 'ltr',
623
+ // So that VoiceOver's focus indicator matches the thumb's dimensions
624
+ width: '100%',
625
+ height: '100%'
626
+ }
627
+ };
628
+ };
629
+ return {
630
+ active,
631
+ axis: axis,
632
+ axisProps,
633
+ dragging,
634
+ focusedThumbIndex,
635
+ getHiddenInputProps,
636
+ getRootProps,
637
+ getThumbProps,
638
+ marks: marks,
639
+ open,
640
+ range,
641
+ rootRef: handleRef,
642
+ trackLeap,
643
+ trackOffset,
644
+ values,
645
+ getThumbStyle
646
+ };
647
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -2,10 +2,10 @@
2
2
 
3
3
  import * as React from 'react';
4
4
  import PropTypes from 'prop-types';
5
- import { useSlotProps } from '@mui/base/utils';
6
5
  import composeClasses from '@mui/utils/composeClasses';
7
- import { ClickAwayListener } from '@mui/base/ClickAwayListener';
8
- import { useSnackbar } from '@mui/base/useSnackbar';
6
+ import useSlotProps from '@mui/utils/useSlotProps';
7
+ import useSnackbar from './useSnackbar';
8
+ import ClickAwayListener from '../ClickAwayListener';
9
9
  import { styled, useTheme } from '../zero-styled';
10
10
  import { useDefaultProps } from '../DefaultPropsProvider';
11
11
  import capitalize from '../utils/capitalize';