@mui/material 9.0.0 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/Accordion/Accordion.d.mts +2 -2
  2. package/Accordion/Accordion.d.ts +2 -2
  3. package/Accordion/Accordion.js +3 -2
  4. package/Accordion/Accordion.mjs +3 -2
  5. package/AccordionSummary/AccordionSummary.js +27 -29
  6. package/AccordionSummary/AccordionSummary.mjs +27 -29
  7. package/Autocomplete/Autocomplete.js +73 -17
  8. package/Autocomplete/Autocomplete.mjs +73 -17
  9. package/Avatar/Avatar.js +4 -0
  10. package/Avatar/Avatar.mjs +4 -0
  11. package/Backdrop/Backdrop.d.mts +2 -2
  12. package/Backdrop/Backdrop.d.ts +2 -2
  13. package/Badge/Badge.js +31 -24
  14. package/Badge/Badge.mjs +31 -24
  15. package/BottomNavigationAction/BottomNavigationAction.js +6 -2
  16. package/BottomNavigationAction/BottomNavigationAction.mjs +6 -2
  17. package/Button/Button.js +19 -6
  18. package/Button/Button.mjs +19 -6
  19. package/ButtonBase/ButtonBase.d.mts +7 -0
  20. package/ButtonBase/ButtonBase.d.ts +7 -0
  21. package/ButtonBase/ButtonBase.js +5 -2
  22. package/ButtonBase/ButtonBase.mjs +5 -2
  23. package/ButtonBase/Ripple.js +21 -11
  24. package/ButtonBase/Ripple.mjs +21 -11
  25. package/ButtonBase/TouchRipple.js +252 -116
  26. package/ButtonBase/TouchRipple.mjs +253 -117
  27. package/CHANGELOG.md +216 -1245
  28. package/CardActionArea/CardActionArea.js +2 -1
  29. package/CardActionArea/CardActionArea.mjs +2 -1
  30. package/Checkbox/Checkbox.js +2 -1
  31. package/Checkbox/Checkbox.mjs +2 -1
  32. package/Chip/Chip.js +2 -1
  33. package/Chip/Chip.mjs +2 -1
  34. package/CircularProgress/CircularProgress.d.mts +12 -2
  35. package/CircularProgress/CircularProgress.d.ts +12 -2
  36. package/CircularProgress/CircularProgress.js +115 -58
  37. package/CircularProgress/CircularProgress.mjs +114 -58
  38. package/ClickAwayListener/ClickAwayListener.js +3 -6
  39. package/ClickAwayListener/ClickAwayListener.mjs +3 -6
  40. package/Collapse/Collapse.d.mts +15 -3
  41. package/Collapse/Collapse.d.ts +15 -3
  42. package/Collapse/Collapse.js +44 -31
  43. package/Collapse/Collapse.mjs +43 -30
  44. package/Dialog/Dialog.d.mts +2 -2
  45. package/Dialog/Dialog.d.ts +2 -2
  46. package/Dialog/Dialog.js +13 -6
  47. package/Dialog/Dialog.mjs +13 -6
  48. package/Drawer/Drawer.d.mts +2 -2
  49. package/Drawer/Drawer.d.ts +2 -2
  50. package/Drawer/Drawer.js +18 -4
  51. package/Drawer/Drawer.mjs +18 -4
  52. package/Fab/Fab.js +9 -2
  53. package/Fab/Fab.mjs +9 -2
  54. package/Fade/Fade.d.mts +15 -2
  55. package/Fade/Fade.d.ts +15 -2
  56. package/Fade/Fade.js +46 -19
  57. package/Fade/Fade.mjs +45 -18
  58. package/FilledInput/FilledInput.d.mts +4 -0
  59. package/FilledInput/FilledInput.d.ts +4 -0
  60. package/FilledInput/FilledInput.js +22 -23
  61. package/FilledInput/FilledInput.mjs +22 -23
  62. package/FormControl/useFormControl.d.mts +12 -2
  63. package/FormControl/useFormControl.d.ts +12 -2
  64. package/FormControl/useFormControl.js +13 -0
  65. package/FormControl/useFormControl.mjs +12 -0
  66. package/FormControlLabel/FormControlLabel.js +5 -8
  67. package/FormControlLabel/FormControlLabel.mjs +5 -8
  68. package/FormGroup/FormGroup.js +2 -5
  69. package/FormGroup/FormGroup.mjs +2 -5
  70. package/FormHelperText/FormHelperText.js +2 -5
  71. package/FormHelperText/FormHelperText.mjs +2 -5
  72. package/FormLabel/FormLabel.js +2 -5
  73. package/FormLabel/FormLabel.mjs +2 -5
  74. package/Grow/Grow.d.mts +15 -2
  75. package/Grow/Grow.d.ts +15 -2
  76. package/Grow/Grow.js +45 -28
  77. package/Grow/Grow.mjs +44 -27
  78. package/IconButton/IconButton.js +3 -9
  79. package/IconButton/IconButton.mjs +3 -9
  80. package/Input/Input.d.mts +4 -0
  81. package/Input/Input.d.ts +4 -0
  82. package/Input/Input.js +9 -2
  83. package/Input/Input.mjs +9 -2
  84. package/InputBase/InputBase.d.mts +2 -1
  85. package/InputBase/InputBase.d.ts +2 -1
  86. package/InputBase/InputBase.js +52 -16
  87. package/InputBase/InputBase.mjs +52 -16
  88. package/InputLabel/InputLabel.js +7 -9
  89. package/InputLabel/InputLabel.mjs +7 -9
  90. package/LICENSE +1 -1
  91. package/LinearProgress/LinearProgress.d.mts +12 -2
  92. package/LinearProgress/LinearProgress.d.ts +12 -2
  93. package/LinearProgress/LinearProgress.js +225 -126
  94. package/LinearProgress/LinearProgress.mjs +224 -126
  95. package/List/List.js +2 -1
  96. package/List/List.mjs +2 -1
  97. package/ListItem/ListItem.js +2 -1
  98. package/ListItem/ListItem.mjs +2 -1
  99. package/ListItemButton/ListItemButton.js +9 -2
  100. package/ListItemButton/ListItemButton.mjs +9 -2
  101. package/Menu/Menu.d.mts +1 -1
  102. package/Menu/Menu.d.ts +1 -1
  103. package/MenuItem/MenuItem.js +7 -1
  104. package/MenuItem/MenuItem.mjs +7 -1
  105. package/MenuList/MenuList.js +2 -1
  106. package/MenuList/MenuList.mjs +2 -1
  107. package/MobileStepper/MobileStepper.js +2 -1
  108. package/MobileStepper/MobileStepper.mjs +2 -1
  109. package/NativeSelect/NativeSelect.js +2 -5
  110. package/NativeSelect/NativeSelect.mjs +2 -5
  111. package/OutlinedInput/NotchedOutline.js +4 -3
  112. package/OutlinedInput/NotchedOutline.mjs +4 -3
  113. package/OutlinedInput/OutlinedInput.js +13 -23
  114. package/OutlinedInput/OutlinedInput.mjs +13 -23
  115. package/PaginationItem/PaginationItem.js +2 -1
  116. package/PaginationItem/PaginationItem.mjs +2 -1
  117. package/Paper/Paper.js +2 -1
  118. package/Paper/Paper.mjs +2 -1
  119. package/PigmentContainer/PigmentContainer.js +0 -1
  120. package/PigmentContainer/PigmentContainer.mjs +0 -1
  121. package/Popover/Popover.d.mts +1 -1
  122. package/Popover/Popover.d.ts +1 -1
  123. package/Popper/BasePopper.js +23 -1
  124. package/Popper/BasePopper.mjs +23 -1
  125. package/README.md +3 -2
  126. package/Radio/RadioButtonIcon.js +3 -2
  127. package/Radio/RadioButtonIcon.mjs +3 -2
  128. package/Rating/Rating.js +2 -1
  129. package/Rating/Rating.mjs +2 -1
  130. package/Select/Select.js +2 -5
  131. package/Select/Select.mjs +2 -5
  132. package/Select/SelectInput.js +276 -24
  133. package/Select/SelectInput.mjs +276 -24
  134. package/Select/utils/closedTypeahead.js +73 -0
  135. package/Select/utils/closedTypeahead.mjs +63 -0
  136. package/Skeleton/Skeleton.js +22 -2
  137. package/Skeleton/Skeleton.mjs +22 -2
  138. package/Slide/Slide.d.mts +15 -2
  139. package/Slide/Slide.d.ts +15 -2
  140. package/Slide/Slide.js +97 -47
  141. package/Slide/Slide.mjs +97 -47
  142. package/Slider/Slider.js +14 -4
  143. package/Slider/Slider.mjs +14 -4
  144. package/Slider/useSlider.js +4 -3
  145. package/Slider/useSlider.mjs +4 -3
  146. package/Snackbar/Snackbar.d.mts +2 -2
  147. package/Snackbar/Snackbar.d.ts +2 -2
  148. package/SpeedDial/SpeedDial.d.mts +1 -1
  149. package/SpeedDial/SpeedDial.d.ts +1 -1
  150. package/SpeedDial/SpeedDial.js +6 -2
  151. package/SpeedDial/SpeedDial.mjs +6 -2
  152. package/SpeedDialAction/SpeedDialAction.js +11 -2
  153. package/SpeedDialAction/SpeedDialAction.mjs +12 -3
  154. package/SpeedDialIcon/SpeedDialIcon.js +40 -37
  155. package/SpeedDialIcon/SpeedDialIcon.mjs +40 -37
  156. package/Step/Step.js +47 -15
  157. package/Step/Step.mjs +47 -15
  158. package/StepButton/StepButton.js +9 -3
  159. package/StepButton/StepButton.mjs +9 -3
  160. package/StepConnector/StepConnector.js +10 -0
  161. package/StepConnector/StepConnector.mjs +10 -0
  162. package/StepContent/StepContent.d.mts +2 -2
  163. package/StepContent/StepContent.d.ts +2 -2
  164. package/StepContent/StepContent.js +26 -2
  165. package/StepContent/StepContent.mjs +26 -2
  166. package/StepIcon/StepIcon.js +2 -1
  167. package/StepIcon/StepIcon.mjs +2 -1
  168. package/StepLabel/StepLabel.js +52 -7
  169. package/StepLabel/StepLabel.mjs +52 -7
  170. package/Stepper/Stepper.d.mts +2 -0
  171. package/Stepper/Stepper.d.ts +2 -0
  172. package/Stepper/Stepper.js +18 -0
  173. package/Stepper/Stepper.mjs +18 -0
  174. package/SvgIcon/SvgIcon.js +2 -1
  175. package/SvgIcon/SvgIcon.mjs +2 -1
  176. package/SwipeableDrawer/SwipeableDrawer.js +21 -6
  177. package/SwipeableDrawer/SwipeableDrawer.mjs +21 -6
  178. package/Switch/Switch.js +10 -8
  179. package/Switch/Switch.mjs +10 -8
  180. package/TableSortLabel/TableSortLabel.js +2 -1
  181. package/TableSortLabel/TableSortLabel.mjs +2 -1
  182. package/Tabs/ScrollbarSize.js +2 -1
  183. package/Tabs/ScrollbarSize.mjs +2 -1
  184. package/Tabs/Tabs.js +16 -4
  185. package/Tabs/Tabs.mjs +16 -4
  186. package/Tooltip/Tooltip.d.mts +2 -2
  187. package/Tooltip/Tooltip.d.ts +2 -2
  188. package/Tooltip/Tooltip.js +29 -108
  189. package/Tooltip/Tooltip.mjs +29 -108
  190. package/Unstable_TrapFocus/FocusTrap.js +60 -22
  191. package/Unstable_TrapFocus/FocusTrap.mjs +60 -22
  192. package/Zoom/Zoom.d.mts +15 -2
  193. package/Zoom/Zoom.d.ts +15 -2
  194. package/Zoom/Zoom.js +43 -16
  195. package/Zoom/Zoom.mjs +42 -15
  196. package/index.js +1 -1
  197. package/index.mjs +1 -1
  198. package/internal/Transition.d.mts +34 -0
  199. package/internal/Transition.d.ts +34 -0
  200. package/internal/Transition.js +444 -0
  201. package/internal/Transition.mjs +436 -0
  202. package/internal/react-transition-group.d.mts +8 -0
  203. package/internal/react-transition-group.d.ts +8 -0
  204. package/package.json +50 -50
  205. package/styles/createMotion.d.mts +8 -0
  206. package/styles/createMotion.d.ts +8 -0
  207. package/styles/createMotion.js +13 -0
  208. package/styles/createMotion.mjs +7 -0
  209. package/styles/createThemeFoundation.d.mts +2 -0
  210. package/styles/createThemeFoundation.d.ts +2 -0
  211. package/styles/createThemeNoVars.d.mts +3 -0
  212. package/styles/createThemeNoVars.d.ts +3 -0
  213. package/styles/createThemeNoVars.js +5 -0
  214. package/styles/createThemeNoVars.mjs +5 -0
  215. package/styles/createTransitions.d.mts +6 -2
  216. package/styles/createTransitions.d.ts +6 -2
  217. package/styles/createTransitions.js +12 -4
  218. package/styles/createTransitions.mjs +12 -4
  219. package/styles/enhanceHighContrast.d.mts +70 -0
  220. package/styles/enhanceHighContrast.d.ts +70 -0
  221. package/styles/enhanceHighContrast.js +502 -0
  222. package/styles/enhanceHighContrast.mjs +495 -0
  223. package/styles/index.d.mts +2 -0
  224. package/styles/index.d.ts +2 -0
  225. package/styles/index.js +8 -0
  226. package/styles/index.mjs +1 -0
  227. package/styles/reducedMotion.d.mts +7 -0
  228. package/styles/reducedMotion.d.ts +7 -0
  229. package/styles/reducedMotion.js +21 -0
  230. package/styles/reducedMotion.mjs +14 -0
  231. package/styles/responsiveFontSizes.js +19 -8
  232. package/styles/responsiveFontSizes.mjs +19 -8
  233. package/styles/shouldSkipGeneratingVar.js +1 -1
  234. package/styles/shouldSkipGeneratingVar.mjs +1 -1
  235. package/styles/stringifyTheme.js +1 -0
  236. package/styles/stringifyTheme.mjs +1 -0
  237. package/styles/useThemeProps.d.mts +3 -3
  238. package/styles/useThemeProps.d.ts +3 -3
  239. package/transitions/index.d.mts +1 -1
  240. package/transitions/index.d.ts +1 -1
  241. package/transitions/index.js +0 -11
  242. package/transitions/index.mjs +1 -1
  243. package/transitions/transition.d.mts +1 -12
  244. package/transitions/transition.d.ts +1 -12
  245. package/transitions/types.d.mts +73 -0
  246. package/transitions/types.d.ts +73 -0
  247. package/transitions/useReducedMotion.d.mts +14 -0
  248. package/transitions/useReducedMotion.d.ts +14 -0
  249. package/transitions/useReducedMotion.js +117 -0
  250. package/transitions/useReducedMotion.mjs +110 -0
  251. package/transitions/utils.d.mts +51 -2
  252. package/transitions/utils.d.ts +51 -2
  253. package/transitions/utils.js +97 -4
  254. package/transitions/utils.mjs +94 -4
  255. package/useAutocomplete/useAutocomplete.d.mts +12 -6
  256. package/useAutocomplete/useAutocomplete.d.ts +12 -6
  257. package/useAutocomplete/useAutocomplete.js +230 -55
  258. package/useAutocomplete/useAutocomplete.mjs +230 -55
  259. package/utils/contains.d.mts +2 -0
  260. package/utils/contains.d.ts +2 -0
  261. package/utils/contains.js +9 -0
  262. package/utils/contains.mjs +2 -0
  263. package/utils/focusable.d.mts +7 -0
  264. package/utils/focusable.d.ts +7 -0
  265. package/utils/focusable.js +20 -0
  266. package/utils/focusable.mjs +13 -0
  267. package/utils/getEventTarget.d.mts +2 -0
  268. package/utils/getEventTarget.d.ts +2 -0
  269. package/utils/getEventTarget.js +9 -0
  270. package/utils/getEventTarget.mjs +2 -0
  271. package/utils/mergeSlotProps.js +2 -8
  272. package/utils/mergeSlotProps.mjs +1 -8
  273. package/version/index.js +2 -2
  274. package/version/index.mjs +2 -2
  275. package/FormControl/formControlState.js +0 -21
  276. package/FormControl/formControlState.mjs +0 -15
  277. /package/transitions/{transition.js → types.js} +0 -0
  278. /package/transitions/{transition.mjs → types.mjs} +0 -0
@@ -8,7 +8,9 @@ import ownerDocument from '@mui/utils/ownerDocument';
8
8
  import getReactElementRef from '@mui/utils/getReactElementRef';
9
9
  import exactProp from '@mui/utils/exactProp';
10
10
  import elementAcceptingRef from '@mui/utils/elementAcceptingRef';
11
+ import contains from "../utils/contains.mjs";
11
12
  import getActiveElement from "../utils/getActiveElement.mjs";
13
+ import { getFocusTarget } from "../utils/focusable.mjs";
12
14
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
15
  // Inspired by https://github.com/focus-trap/tabbable
14
16
  const candidatesSelector = ['input', 'select', 'textarea', 'a[href]', 'button', '[tabindex]', 'audio[controls]', 'video[controls]', '[contenteditable]:not([contenteditable="false"])'].join(',');
@@ -107,34 +109,36 @@ function FocusTrap(props) {
107
109
  activated.current = !disableAutoFocus;
108
110
  }, [disableAutoFocus, open]);
109
111
  React.useEffect(() => {
112
+ // Reset on every mount — React 18 Strict Mode double-mounts leave this
113
+ // stuck at `true` after the cleanup of the previous mount set it.
114
+ ignoreNextEnforceFocus.current = false;
115
+
110
116
  // We might render an empty child.
111
117
  if (!open || !rootRef.current) {
112
118
  return;
113
119
  }
114
120
  const doc = ownerDocument(rootRef.current);
115
121
  const activeElement = getActiveElement(doc);
116
- if (!rootRef.current.contains(activeElement)) {
117
- if (!rootRef.current.hasAttribute('tabIndex')) {
122
+
123
+ // Prefer the explicitly marked focusable element. Fall back to the root
124
+ // element for generic FocusTrap usage.
125
+ const focusTarget = getFocusTarget(rootRef.current) ?? rootRef.current;
126
+ if (!contains(rootRef.current, activeElement)) {
127
+ if (!focusTarget.hasAttribute('tabIndex')) {
118
128
  if (process.env.NODE_ENV !== 'production') {
119
129
  console.error(['MUI: The modal content node does not accept focus.', 'For the benefit of assistive technologies, ' + 'the tabIndex of the node is being set to "-1".'].join('\n'));
120
130
  }
121
- rootRef.current.setAttribute('tabIndex', '-1');
131
+ focusTarget.setAttribute('tabIndex', '-1');
122
132
  }
123
133
  if (activated.current) {
124
- rootRef.current.focus();
134
+ focusTarget.focus();
125
135
  }
126
136
  }
127
137
  return () => {
128
138
  // restoreLastFocus()
129
- if (!disableRestoreFocus) {
130
- // In IE11 it is possible for document.activeElement to be null resulting
131
- // in nodeToRestore.current being null.
132
- // Not all elements in IE11 have a focus method.
133
- // Once IE11 support is dropped the focus() call can be unconditional.
134
- if (nodeToRestore.current && nodeToRestore.current.focus) {
135
- ignoreNextEnforceFocus.current = true;
136
- nodeToRestore.current.focus();
137
- }
139
+ if (!disableRestoreFocus && nodeToRestore.current) {
140
+ ignoreNextEnforceFocus.current = true;
141
+ nodeToRestore.current.focus();
138
142
  nodeToRestore.current = null;
139
143
  }
140
144
  };
@@ -153,17 +157,51 @@ function FocusTrap(props) {
153
157
  if (disableEnforceFocus || !isEnabled() || nativeEvent.key !== 'Tab') {
154
158
  return;
155
159
  }
160
+ const rootElement = rootRef.current;
156
161
  const activeElement = getActiveElement(doc);
162
+ if (rootElement === null) {
163
+ return;
164
+ }
165
+ const focusTarget = getFocusTarget(rootElement);
166
+ const isFocusStart = activeElement === rootElement || activeElement === focusTarget;
157
167
 
158
- // Make sure the next tab starts from the right place.
159
- // activeElement refers to the origin.
160
- if (activeElement === rootRef.current && nativeEvent.shiftKey) {
161
- // We need to ignore the next contain as
162
- // it will try to move the focus back to the rootRef element.
163
- ignoreNextEnforceFocus.current = true;
164
- if (sentinelEnd.current) {
165
- sentinelEnd.current.focus();
168
+ // Marked focus targets can be non-tabbable, but should start tabbing
169
+ // from the first/last tabbable child.
170
+ if (isFocusStart) {
171
+ const tabbable = getTabbable(rootElement);
172
+ if (tabbable.length === 0) {
173
+ return;
174
+ }
175
+ nativeEvent.preventDefault();
176
+ if (nativeEvent.shiftKey) {
177
+ tabbable[tabbable.length - 1].focus();
178
+ } else {
179
+ tabbable[0].focus();
180
+ }
181
+ return;
182
+ }
183
+ if (contains(rootElement, activeElement)) {
184
+ const tabbable = getTabbable(rootElement);
185
+ const currentIndex = tabbable.indexOf(activeElement);
186
+ if (currentIndex === -1) {
187
+ // Leave shadow-root descendants to native tab handling.
188
+ return;
189
+ }
190
+ const hasPositiveTabIndex = tabbable.some(node => getTabIndex(node) > 0);
191
+
192
+ // Positive tabIndex needs the computed order; regular tabIndex=0 can
193
+ // use native tab handling.
194
+ if (!hasPositiveTabIndex) {
195
+ return;
196
+ }
197
+ nativeEvent.preventDefault();
198
+ let nextIndex = 0;
199
+ if (nativeEvent.shiftKey) {
200
+ nextIndex = currentIndex <= 0 ? tabbable.length - 1 : currentIndex - 1;
201
+ } else {
202
+ nextIndex = currentIndex === tabbable.length - 1 ? 0 : currentIndex + 1;
166
203
  }
204
+ tabbable[nextIndex].focus();
167
205
  }
168
206
  };
169
207
  const contain = () => {
@@ -181,7 +219,7 @@ function FocusTrap(props) {
181
219
  }
182
220
 
183
221
  // The focus is already inside
184
- if (rootElement.contains(activeEl)) {
222
+ if (contains(rootElement, activeEl)) {
185
223
  return;
186
224
  }
187
225
 
package/Zoom/Zoom.d.mts CHANGED
@@ -1,6 +1,15 @@
1
1
  import * as React from 'react';
2
- import { TransitionProps } from "../transitions/transition.mjs";
2
+ import { TransitionProps } from "../transitions/types.mjs";
3
3
  export interface ZoomProps extends TransitionProps {
4
+ /**
5
+ * Add a custom transition end trigger.
6
+ * Use it when you need custom logic to decide when the transition has ended.
7
+ * Note: Timeouts are still used as a fallback if provided.
8
+ *
9
+ * @param {HTMLElement} node The transitioning DOM node.
10
+ * @param {Function} done Call this when the transition has finished.
11
+ */
12
+ addEndListener?: TransitionProps['addEndListener'] | undefined;
4
13
  /**
5
14
  * Perform the enter transition when it first mounts if `in` is also `true`.
6
15
  * Set this to `false` to disable this behavior.
@@ -11,6 +20,11 @@ export interface ZoomProps extends TransitionProps {
11
20
  * A single child content element.
12
21
  */
13
22
  children: React.ReactElement<unknown, any>;
23
+ /**
24
+ * If `true`, the transition ignores `theme.motion.reducedMotion` and keeps its normal timing.
25
+ * @default false
26
+ */
27
+ disablePrefersReducedMotion?: boolean | undefined;
14
28
  /**
15
29
  * The transition timing function.
16
30
  * You may specify a single easing or a object containing enter and exit values.
@@ -35,7 +49,6 @@ export interface ZoomProps extends TransitionProps {
35
49
  /**
36
50
  * The Zoom transition can be used for the floating variant of the
37
51
  * [Button](https://mui.com/material-ui/react-floating-action-button/#animation) component.
38
- * It uses [react-transition-group](https://github.com/reactjs/react-transition-group) internally.
39
52
  *
40
53
  * Demos:
41
54
  *
package/Zoom/Zoom.d.ts CHANGED
@@ -1,6 +1,15 @@
1
1
  import * as React from 'react';
2
- import { TransitionProps } from "../transitions/transition.js";
2
+ import { TransitionProps } from "../transitions/types.js";
3
3
  export interface ZoomProps extends TransitionProps {
4
+ /**
5
+ * Add a custom transition end trigger.
6
+ * Use it when you need custom logic to decide when the transition has ended.
7
+ * Note: Timeouts are still used as a fallback if provided.
8
+ *
9
+ * @param {HTMLElement} node The transitioning DOM node.
10
+ * @param {Function} done Call this when the transition has finished.
11
+ */
12
+ addEndListener?: TransitionProps['addEndListener'] | undefined;
4
13
  /**
5
14
  * Perform the enter transition when it first mounts if `in` is also `true`.
6
15
  * Set this to `false` to disable this behavior.
@@ -11,6 +20,11 @@ export interface ZoomProps extends TransitionProps {
11
20
  * A single child content element.
12
21
  */
13
22
  children: React.ReactElement<unknown, any>;
23
+ /**
24
+ * If `true`, the transition ignores `theme.motion.reducedMotion` and keeps its normal timing.
25
+ * @default false
26
+ */
27
+ disablePrefersReducedMotion?: boolean | undefined;
14
28
  /**
15
29
  * The transition timing function.
16
30
  * You may specify a single easing or a object containing enter and exit values.
@@ -35,7 +49,6 @@ export interface ZoomProps extends TransitionProps {
35
49
  /**
36
50
  * The Zoom transition can be used for the floating variant of the
37
51
  * [Button](https://mui.com/material-ui/react-floating-action-button/#animation) component.
38
- * It uses [react-transition-group](https://github.com/reactjs/react-transition-group) internally.
39
52
  *
40
53
  * Demos:
41
54
  *
package/Zoom/Zoom.js CHANGED
@@ -9,9 +9,10 @@ Object.defineProperty(exports, "__esModule", {
9
9
  exports.default = void 0;
10
10
  var React = _interopRequireWildcard(require("react"));
11
11
  var _propTypes = _interopRequireDefault(require("prop-types"));
12
- var _reactTransitionGroup = require("react-transition-group");
13
12
  var _elementAcceptingRef = _interopRequireDefault(require("@mui/utils/elementAcceptingRef"));
14
13
  var _getReactElementRef = _interopRequireDefault(require("@mui/utils/getReactElementRef"));
14
+ var _Transition = _interopRequireDefault(require("../internal/Transition"));
15
+ var _useReducedMotion = _interopRequireDefault(require("../transitions/useReducedMotion"));
15
16
  var _zeroStyled = require("../zero-styled");
16
17
  var _utils = require("../transitions/utils");
17
18
  var _useForkRef = _interopRequireDefault(require("../utils/useForkRef"));
@@ -38,7 +39,6 @@ const hiddenStyles = {
38
39
  /**
39
40
  * The Zoom transition can be used for the floating variant of the
40
41
  * [Button](/material-ui/react-floating-action-button/#animation) component.
41
- * It uses [react-transition-group](https://github.com/reactjs/react-transition-group) internally.
42
42
  */
43
43
  const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
44
44
  const theme = (0, _zeroStyled.useTheme)();
@@ -50,6 +50,7 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
50
50
  addEndListener,
51
51
  appear = true,
52
52
  children,
53
+ disablePrefersReducedMotion = false,
53
54
  easing,
54
55
  in: inProp,
55
56
  onEnter,
@@ -62,12 +63,14 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
62
63
  timeout = defaultTimeout,
63
64
  ...other
64
65
  } = props;
66
+ const reducedMotion = (0, _useReducedMotion.default)(theme.motion.reducedMotion, disablePrefersReducedMotion);
65
67
  const nodeRef = React.useRef(null);
66
68
  const handleRef = (0, _useForkRef.default)(nodeRef, (0, _getReactElementRef.default)(children), ref);
67
69
  const handleEntering = (0, _utils.normalizedTransitionCallback)(nodeRef, onEntering);
68
70
  const handleEnter = (0, _utils.normalizedTransitionCallback)(nodeRef, (node, isAppearing) => {
69
- (0, _utils.reflow)(node); // So the animation always start from the start.
70
-
71
+ if (!reducedMotion.shouldReduceMotion) {
72
+ (0, _utils.reflow)(node); // Force layout so the animation starts from the initial styles.
73
+ }
71
74
  const transitionProps = (0, _utils.getTransitionProps)({
72
75
  style,
73
76
  timeout,
@@ -75,7 +78,15 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
75
78
  }, {
76
79
  mode: 'enter'
77
80
  });
78
- node.style.transition = theme.transitions.create('transform', transitionProps);
81
+ const transitionTiming = reducedMotion.getTransitionTiming({
82
+ duration: transitionProps.duration,
83
+ delay: transitionProps.delay
84
+ });
85
+ node.style.transition = theme.transitions.create('transform', {
86
+ duration: transitionTiming.duration,
87
+ easing: transitionProps.easing,
88
+ delay: transitionTiming.delay
89
+ });
79
90
  if (onEnter) {
80
91
  onEnter(node, isAppearing);
81
92
  }
@@ -90,7 +101,15 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
90
101
  }, {
91
102
  mode: 'exit'
92
103
  });
93
- node.style.transition = theme.transitions.create('transform', transitionProps);
104
+ const transitionTiming = reducedMotion.getTransitionTiming({
105
+ duration: transitionProps.duration,
106
+ delay: transitionProps.delay
107
+ });
108
+ node.style.transition = theme.transitions.create('transform', {
109
+ duration: transitionTiming.duration,
110
+ easing: transitionProps.easing,
111
+ delay: transitionTiming.delay
112
+ });
94
113
  if (onExit) {
95
114
  onExit(node);
96
115
  }
@@ -101,13 +120,10 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
101
120
  onExited(node);
102
121
  }
103
122
  });
104
- const handleAddEndListener = next => {
105
- if (addEndListener) {
106
- // Old call signature before `react-transition-group` implemented `nodeRef`
107
- addEndListener(nodeRef.current, next);
108
- }
109
- };
110
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactTransitionGroup.Transition, {
123
+ const handleAddEndListener = addEndListener ? next => {
124
+ addEndListener(nodeRef.current, next);
125
+ } : undefined;
126
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Transition.default, {
111
127
  appear: appear,
112
128
  in: inProp,
113
129
  nodeRef: nodeRef,
@@ -118,12 +134,15 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
118
134
  onExited: handleExited,
119
135
  onExiting: handleExiting,
120
136
  addEndListener: handleAddEndListener,
137
+ reduceMotion: reducedMotion.shouldReduceMotion,
121
138
  timeout: timeout,
122
139
  ...other,
123
140
  children: (state, {
124
141
  ownerState,
125
142
  ...restChildProps
126
143
  }) => {
144
+ // Do not pass ownerState to a DOM child. ownerState is only for
145
+ // Material UI styling, and React would treat it as an invalid DOM attribute.
127
146
  const childStyle = (0, _utils.getTransitionChildStyle)(state, inProp, styles, hiddenStyles, style, children.props.style);
128
147
  return /*#__PURE__*/React.cloneElement(children, {
129
148
  style: childStyle,
@@ -139,9 +158,12 @@ process.env.NODE_ENV !== "production" ? Zoom.propTypes /* remove-proptypes */ =
139
158
  // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
140
159
  // └─────────────────────────────────────────────────────────────────────┘
141
160
  /**
142
- * Add a custom transition end trigger. Called with the transitioning DOM
143
- * node and a done callback. Allows for more fine grained transition end
144
- * logic. Note: Timeouts are still used as a fallback if provided.
161
+ * Add a custom transition end trigger.
162
+ * Use it when you need custom logic to decide when the transition has ended.
163
+ * Note: Timeouts are still used as a fallback if provided.
164
+ *
165
+ * @param {HTMLElement} node The transitioning DOM node.
166
+ * @param {Function} done Call this when the transition has finished.
145
167
  */
146
168
  addEndListener: _propTypes.default.func,
147
169
  /**
@@ -154,6 +176,11 @@ process.env.NODE_ENV !== "production" ? Zoom.propTypes /* remove-proptypes */ =
154
176
  * A single child content element.
155
177
  */
156
178
  children: _elementAcceptingRef.default.isRequired,
179
+ /**
180
+ * If `true`, the transition ignores `theme.motion.reducedMotion` and keeps its normal timing.
181
+ * @default false
182
+ */
183
+ disablePrefersReducedMotion: _propTypes.default.bool,
157
184
  /**
158
185
  * The transition timing function.
159
186
  * You may specify a single easing or a object containing enter and exit values.
package/Zoom/Zoom.mjs CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  import * as React from 'react';
4
4
  import PropTypes from 'prop-types';
5
- import { Transition } from 'react-transition-group';
6
5
  import elementAcceptingRef from '@mui/utils/elementAcceptingRef';
7
6
  import getReactElementRef from '@mui/utils/getReactElementRef';
7
+ import Transition from "../internal/Transition.mjs";
8
+ import useReducedMotion from "../transitions/useReducedMotion.mjs";
8
9
  import { useTheme } from "../zero-styled/index.mjs";
9
10
  import { normalizedTransitionCallback, reflow, getTransitionProps, getTransitionChildStyle } from "../transitions/utils.mjs";
10
11
  import useForkRef from "../utils/useForkRef.mjs";
@@ -31,7 +32,6 @@ const hiddenStyles = {
31
32
  /**
32
33
  * The Zoom transition can be used for the floating variant of the
33
34
  * [Button](/material-ui/react-floating-action-button/#animation) component.
34
- * It uses [react-transition-group](https://github.com/reactjs/react-transition-group) internally.
35
35
  */
36
36
  const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
37
37
  const theme = useTheme();
@@ -43,6 +43,7 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
43
43
  addEndListener,
44
44
  appear = true,
45
45
  children,
46
+ disablePrefersReducedMotion = false,
46
47
  easing,
47
48
  in: inProp,
48
49
  onEnter,
@@ -55,12 +56,14 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
55
56
  timeout = defaultTimeout,
56
57
  ...other
57
58
  } = props;
59
+ const reducedMotion = useReducedMotion(theme.motion.reducedMotion, disablePrefersReducedMotion);
58
60
  const nodeRef = React.useRef(null);
59
61
  const handleRef = useForkRef(nodeRef, getReactElementRef(children), ref);
60
62
  const handleEntering = normalizedTransitionCallback(nodeRef, onEntering);
61
63
  const handleEnter = normalizedTransitionCallback(nodeRef, (node, isAppearing) => {
62
- reflow(node); // So the animation always start from the start.
63
-
64
+ if (!reducedMotion.shouldReduceMotion) {
65
+ reflow(node); // Force layout so the animation starts from the initial styles.
66
+ }
64
67
  const transitionProps = getTransitionProps({
65
68
  style,
66
69
  timeout,
@@ -68,7 +71,15 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
68
71
  }, {
69
72
  mode: 'enter'
70
73
  });
71
- node.style.transition = theme.transitions.create('transform', transitionProps);
74
+ const transitionTiming = reducedMotion.getTransitionTiming({
75
+ duration: transitionProps.duration,
76
+ delay: transitionProps.delay
77
+ });
78
+ node.style.transition = theme.transitions.create('transform', {
79
+ duration: transitionTiming.duration,
80
+ easing: transitionProps.easing,
81
+ delay: transitionTiming.delay
82
+ });
72
83
  if (onEnter) {
73
84
  onEnter(node, isAppearing);
74
85
  }
@@ -83,7 +94,15 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
83
94
  }, {
84
95
  mode: 'exit'
85
96
  });
86
- node.style.transition = theme.transitions.create('transform', transitionProps);
97
+ const transitionTiming = reducedMotion.getTransitionTiming({
98
+ duration: transitionProps.duration,
99
+ delay: transitionProps.delay
100
+ });
101
+ node.style.transition = theme.transitions.create('transform', {
102
+ duration: transitionTiming.duration,
103
+ easing: transitionProps.easing,
104
+ delay: transitionTiming.delay
105
+ });
87
106
  if (onExit) {
88
107
  onExit(node);
89
108
  }
@@ -94,12 +113,9 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
94
113
  onExited(node);
95
114
  }
96
115
  });
97
- const handleAddEndListener = next => {
98
- if (addEndListener) {
99
- // Old call signature before `react-transition-group` implemented `nodeRef`
100
- addEndListener(nodeRef.current, next);
101
- }
102
- };
116
+ const handleAddEndListener = addEndListener ? next => {
117
+ addEndListener(nodeRef.current, next);
118
+ } : undefined;
103
119
  return /*#__PURE__*/_jsx(Transition, {
104
120
  appear: appear,
105
121
  in: inProp,
@@ -111,12 +127,15 @@ const Zoom = /*#__PURE__*/React.forwardRef(function Zoom(props, ref) {
111
127
  onExited: handleExited,
112
128
  onExiting: handleExiting,
113
129
  addEndListener: handleAddEndListener,
130
+ reduceMotion: reducedMotion.shouldReduceMotion,
114
131
  timeout: timeout,
115
132
  ...other,
116
133
  children: (state, {
117
134
  ownerState,
118
135
  ...restChildProps
119
136
  }) => {
137
+ // Do not pass ownerState to a DOM child. ownerState is only for
138
+ // Material UI styling, and React would treat it as an invalid DOM attribute.
120
139
  const childStyle = getTransitionChildStyle(state, inProp, styles, hiddenStyles, style, children.props.style);
121
140
  return /*#__PURE__*/React.cloneElement(children, {
122
141
  style: childStyle,
@@ -132,9 +151,12 @@ process.env.NODE_ENV !== "production" ? Zoom.propTypes /* remove-proptypes */ =
132
151
  // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
133
152
  // └─────────────────────────────────────────────────────────────────────┘
134
153
  /**
135
- * Add a custom transition end trigger. Called with the transitioning DOM
136
- * node and a done callback. Allows for more fine grained transition end
137
- * logic. Note: Timeouts are still used as a fallback if provided.
154
+ * Add a custom transition end trigger.
155
+ * Use it when you need custom logic to decide when the transition has ended.
156
+ * Note: Timeouts are still used as a fallback if provided.
157
+ *
158
+ * @param {HTMLElement} node The transitioning DOM node.
159
+ * @param {Function} done Call this when the transition has finished.
138
160
  */
139
161
  addEndListener: PropTypes.func,
140
162
  /**
@@ -147,6 +169,11 @@ process.env.NODE_ENV !== "production" ? Zoom.propTypes /* remove-proptypes */ =
147
169
  * A single child content element.
148
170
  */
149
171
  children: elementAcceptingRef.isRequired,
172
+ /**
173
+ * If `true`, the transition ignores `theme.motion.reducedMotion` and keeps its normal timing.
174
+ * @default false
175
+ */
176
+ disablePrefersReducedMotion: PropTypes.bool,
150
177
  /**
151
178
  * The transition timing function.
152
179
  * You may specify a single easing or a object containing enter and exit values.
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/material v9.0.0
2
+ * @mui/material v9.1.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/material v9.0.0
2
+ * @mui/material v9.1.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -0,0 +1,34 @@
1
+ import * as React from 'react';
2
+ type RenderedTransitionStatus = 'entering' | 'entered' | 'exiting' | 'exited';
3
+ type TransitionEndListener = ((done: () => void) => void) | ((node: HTMLElement, done: () => void) => void);
4
+ interface InternalTransitionProps {
5
+ in?: boolean | undefined;
6
+ appear?: boolean | undefined;
7
+ enter?: boolean | undefined;
8
+ exit?: boolean | undefined;
9
+ timeout?: number | null | {
10
+ appear?: number | undefined;
11
+ enter?: number | undefined;
12
+ exit?: number | undefined;
13
+ } | undefined;
14
+ nodeRef: React.RefObject<HTMLElement | null>;
15
+ mountOnEnter?: boolean | undefined;
16
+ unmountOnExit?: boolean | undefined;
17
+ addEndListener?: TransitionEndListener | undefined;
18
+ reduceMotion?: boolean | undefined;
19
+ getAutoTimeout?: (() => number | null | undefined) | undefined;
20
+ onEnter?: ((isAppearing: boolean) => void) | undefined;
21
+ onEntering?: ((isAppearing: boolean) => void) | undefined;
22
+ onEntered?: ((isAppearing: boolean) => void) | undefined;
23
+ onExit?: (() => void) | undefined;
24
+ onExiting?: (() => void) | undefined;
25
+ onExited?: (() => void) | undefined;
26
+ children: (status: RenderedTransitionStatus, childProps: Record<string, unknown>) => React.ReactNode;
27
+ [key: string]: unknown;
28
+ }
29
+ declare function Transition(props: InternalTransitionProps): React.ReactNode;
30
+ declare namespace Transition {
31
+ var propTypes: any;
32
+ }
33
+ export default Transition;
34
+ export type { InternalTransitionProps, RenderedTransitionStatus };
@@ -0,0 +1,34 @@
1
+ import * as React from 'react';
2
+ type RenderedTransitionStatus = 'entering' | 'entered' | 'exiting' | 'exited';
3
+ type TransitionEndListener = ((done: () => void) => void) | ((node: HTMLElement, done: () => void) => void);
4
+ interface InternalTransitionProps {
5
+ in?: boolean | undefined;
6
+ appear?: boolean | undefined;
7
+ enter?: boolean | undefined;
8
+ exit?: boolean | undefined;
9
+ timeout?: number | null | {
10
+ appear?: number | undefined;
11
+ enter?: number | undefined;
12
+ exit?: number | undefined;
13
+ } | undefined;
14
+ nodeRef: React.RefObject<HTMLElement | null>;
15
+ mountOnEnter?: boolean | undefined;
16
+ unmountOnExit?: boolean | undefined;
17
+ addEndListener?: TransitionEndListener | undefined;
18
+ reduceMotion?: boolean | undefined;
19
+ getAutoTimeout?: (() => number | null | undefined) | undefined;
20
+ onEnter?: ((isAppearing: boolean) => void) | undefined;
21
+ onEntering?: ((isAppearing: boolean) => void) | undefined;
22
+ onEntered?: ((isAppearing: boolean) => void) | undefined;
23
+ onExit?: (() => void) | undefined;
24
+ onExiting?: (() => void) | undefined;
25
+ onExited?: (() => void) | undefined;
26
+ children: (status: RenderedTransitionStatus, childProps: Record<string, unknown>) => React.ReactNode;
27
+ [key: string]: unknown;
28
+ }
29
+ declare function Transition(props: InternalTransitionProps): React.ReactNode;
30
+ declare namespace Transition {
31
+ var propTypes: any;
32
+ }
33
+ export default Transition;
34
+ export type { InternalTransitionProps, RenderedTransitionStatus };