@mui/material 9.0.1 → 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 (206) 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 +8 -6
  8. package/Autocomplete/Autocomplete.mjs +8 -6
  9. package/Backdrop/Backdrop.d.mts +2 -2
  10. package/Backdrop/Backdrop.d.ts +2 -2
  11. package/Badge/Badge.js +28 -24
  12. package/Badge/Badge.mjs +28 -24
  13. package/BottomNavigationAction/BottomNavigationAction.js +6 -2
  14. package/BottomNavigationAction/BottomNavigationAction.mjs +6 -2
  15. package/Button/Button.js +11 -15
  16. package/Button/Button.mjs +11 -15
  17. package/ButtonBase/Ripple.js +21 -11
  18. package/ButtonBase/Ripple.mjs +21 -11
  19. package/ButtonBase/TouchRipple.js +252 -116
  20. package/ButtonBase/TouchRipple.mjs +253 -117
  21. package/CHANGELOG.md +84 -0
  22. package/CardActionArea/CardActionArea.js +2 -1
  23. package/CardActionArea/CardActionArea.mjs +2 -1
  24. package/Chip/Chip.js +2 -1
  25. package/Chip/Chip.mjs +2 -1
  26. package/CircularProgress/CircularProgress.js +85 -55
  27. package/CircularProgress/CircularProgress.mjs +84 -55
  28. package/Collapse/Collapse.d.mts +15 -3
  29. package/Collapse/Collapse.d.ts +15 -3
  30. package/Collapse/Collapse.js +44 -31
  31. package/Collapse/Collapse.mjs +43 -30
  32. package/Dialog/Dialog.d.mts +2 -2
  33. package/Dialog/Dialog.d.ts +2 -2
  34. package/Dialog/Dialog.js +2 -0
  35. package/Dialog/Dialog.mjs +2 -0
  36. package/Drawer/Drawer.d.mts +2 -2
  37. package/Drawer/Drawer.d.ts +2 -2
  38. package/Fab/Fab.js +2 -1
  39. package/Fab/Fab.mjs +2 -1
  40. package/Fade/Fade.d.mts +15 -2
  41. package/Fade/Fade.d.ts +15 -2
  42. package/Fade/Fade.js +46 -19
  43. package/Fade/Fade.mjs +45 -18
  44. package/FilledInput/FilledInput.js +4 -3
  45. package/FilledInput/FilledInput.mjs +4 -3
  46. package/Grow/Grow.d.mts +15 -2
  47. package/Grow/Grow.d.ts +15 -2
  48. package/Grow/Grow.js +45 -28
  49. package/Grow/Grow.mjs +44 -27
  50. package/IconButton/IconButton.js +2 -1
  51. package/IconButton/IconButton.mjs +2 -1
  52. package/Input/Input.js +3 -2
  53. package/Input/Input.mjs +3 -2
  54. package/InputBase/InputBase.js +2 -1
  55. package/InputBase/InputBase.mjs +2 -1
  56. package/InputLabel/InputLabel.js +2 -1
  57. package/InputLabel/InputLabel.mjs +2 -1
  58. package/LICENSE +1 -1
  59. package/LinearProgress/LinearProgress.js +187 -120
  60. package/LinearProgress/LinearProgress.mjs +186 -120
  61. package/ListItem/ListItem.js +2 -1
  62. package/ListItem/ListItem.mjs +2 -1
  63. package/ListItemButton/ListItemButton.js +2 -1
  64. package/ListItemButton/ListItemButton.mjs +2 -1
  65. package/Menu/Menu.d.mts +1 -1
  66. package/Menu/Menu.d.ts +1 -1
  67. package/MobileStepper/MobileStepper.js +2 -1
  68. package/MobileStepper/MobileStepper.mjs +2 -1
  69. package/OutlinedInput/NotchedOutline.js +4 -3
  70. package/OutlinedInput/NotchedOutline.mjs +4 -3
  71. package/PaginationItem/PaginationItem.js +2 -1
  72. package/PaginationItem/PaginationItem.mjs +2 -1
  73. package/Paper/Paper.js +2 -1
  74. package/Paper/Paper.mjs +2 -1
  75. package/Popover/Popover.d.mts +1 -1
  76. package/Popover/Popover.d.ts +1 -1
  77. package/README.md +3 -2
  78. package/Radio/RadioButtonIcon.js +3 -2
  79. package/Radio/RadioButtonIcon.mjs +3 -2
  80. package/Rating/Rating.js +2 -1
  81. package/Rating/Rating.mjs +2 -1
  82. package/Select/SelectInput.js +115 -25
  83. package/Select/SelectInput.mjs +115 -25
  84. package/Select/utils/closedTypeahead.js +73 -0
  85. package/Select/utils/closedTypeahead.mjs +63 -0
  86. package/Skeleton/Skeleton.js +22 -2
  87. package/Skeleton/Skeleton.mjs +22 -2
  88. package/Slide/Slide.d.mts +15 -2
  89. package/Slide/Slide.d.ts +15 -2
  90. package/Slide/Slide.js +53 -25
  91. package/Slide/Slide.mjs +52 -24
  92. package/Slider/Slider.js +4 -3
  93. package/Slider/Slider.mjs +4 -3
  94. package/Slider/useSlider.js +1 -1
  95. package/Slider/useSlider.mjs +1 -1
  96. package/Snackbar/Snackbar.d.mts +2 -2
  97. package/Snackbar/Snackbar.d.ts +2 -2
  98. package/SpeedDial/SpeedDial.d.mts +1 -1
  99. package/SpeedDial/SpeedDial.d.ts +1 -1
  100. package/SpeedDial/SpeedDial.js +6 -2
  101. package/SpeedDial/SpeedDial.mjs +6 -2
  102. package/SpeedDialAction/SpeedDialAction.js +11 -2
  103. package/SpeedDialAction/SpeedDialAction.mjs +12 -3
  104. package/SpeedDialIcon/SpeedDialIcon.js +40 -37
  105. package/SpeedDialIcon/SpeedDialIcon.mjs +40 -37
  106. package/Step/Step.js +47 -15
  107. package/Step/Step.mjs +47 -15
  108. package/StepButton/StepButton.js +9 -3
  109. package/StepButton/StepButton.mjs +9 -3
  110. package/StepConnector/StepConnector.js +10 -0
  111. package/StepConnector/StepConnector.mjs +10 -0
  112. package/StepContent/StepContent.d.mts +2 -2
  113. package/StepContent/StepContent.d.ts +2 -2
  114. package/StepContent/StepContent.js +26 -2
  115. package/StepContent/StepContent.mjs +26 -2
  116. package/StepIcon/StepIcon.js +2 -1
  117. package/StepIcon/StepIcon.mjs +2 -1
  118. package/StepLabel/StepLabel.js +52 -7
  119. package/StepLabel/StepLabel.mjs +52 -7
  120. package/Stepper/Stepper.d.mts +2 -0
  121. package/Stepper/Stepper.d.ts +2 -0
  122. package/Stepper/Stepper.js +18 -0
  123. package/Stepper/Stepper.mjs +18 -0
  124. package/SvgIcon/SvgIcon.js +2 -1
  125. package/SvgIcon/SvgIcon.mjs +2 -1
  126. package/SwipeableDrawer/SwipeableDrawer.js +14 -3
  127. package/SwipeableDrawer/SwipeableDrawer.mjs +14 -3
  128. package/Switch/Switch.js +3 -2
  129. package/Switch/Switch.mjs +3 -2
  130. package/TableSortLabel/TableSortLabel.js +2 -1
  131. package/TableSortLabel/TableSortLabel.mjs +2 -1
  132. package/Tabs/Tabs.js +14 -3
  133. package/Tabs/Tabs.mjs +14 -3
  134. package/Tooltip/Tooltip.d.mts +2 -2
  135. package/Tooltip/Tooltip.d.ts +2 -2
  136. package/Tooltip/Tooltip.js +3 -0
  137. package/Tooltip/Tooltip.mjs +3 -0
  138. package/Unstable_TrapFocus/FocusTrap.js +42 -8
  139. package/Unstable_TrapFocus/FocusTrap.mjs +42 -8
  140. package/Zoom/Zoom.d.mts +15 -2
  141. package/Zoom/Zoom.d.ts +15 -2
  142. package/Zoom/Zoom.js +43 -16
  143. package/Zoom/Zoom.mjs +42 -15
  144. package/index.js +1 -1
  145. package/index.mjs +1 -1
  146. package/internal/Transition.d.mts +34 -0
  147. package/internal/Transition.d.ts +34 -0
  148. package/internal/Transition.js +444 -0
  149. package/internal/Transition.mjs +436 -0
  150. package/internal/react-transition-group.d.mts +8 -0
  151. package/internal/react-transition-group.d.ts +8 -0
  152. package/package.json +6 -6
  153. package/styles/createMotion.d.mts +8 -0
  154. package/styles/createMotion.d.ts +8 -0
  155. package/styles/createMotion.js +13 -0
  156. package/styles/createMotion.mjs +7 -0
  157. package/styles/createThemeFoundation.d.mts +2 -0
  158. package/styles/createThemeFoundation.d.ts +2 -0
  159. package/styles/createThemeNoVars.d.mts +3 -0
  160. package/styles/createThemeNoVars.d.ts +3 -0
  161. package/styles/createThemeNoVars.js +5 -0
  162. package/styles/createThemeNoVars.mjs +5 -0
  163. package/styles/createTransitions.d.mts +6 -2
  164. package/styles/createTransitions.d.ts +6 -2
  165. package/styles/createTransitions.js +12 -4
  166. package/styles/createTransitions.mjs +12 -4
  167. package/styles/enhanceHighContrast.d.mts +70 -0
  168. package/styles/enhanceHighContrast.d.ts +70 -0
  169. package/styles/enhanceHighContrast.js +502 -0
  170. package/styles/enhanceHighContrast.mjs +495 -0
  171. package/styles/index.d.mts +2 -0
  172. package/styles/index.d.ts +2 -0
  173. package/styles/index.js +8 -0
  174. package/styles/index.mjs +1 -0
  175. package/styles/reducedMotion.d.mts +7 -0
  176. package/styles/reducedMotion.d.ts +7 -0
  177. package/styles/reducedMotion.js +21 -0
  178. package/styles/reducedMotion.mjs +14 -0
  179. package/styles/shouldSkipGeneratingVar.js +1 -1
  180. package/styles/shouldSkipGeneratingVar.mjs +1 -1
  181. package/styles/stringifyTheme.js +1 -0
  182. package/styles/stringifyTheme.mjs +1 -0
  183. package/transitions/index.d.mts +1 -1
  184. package/transitions/index.d.ts +1 -1
  185. package/transitions/index.js +0 -11
  186. package/transitions/index.mjs +1 -1
  187. package/transitions/transition.d.mts +1 -12
  188. package/transitions/transition.d.ts +1 -12
  189. package/transitions/types.d.mts +73 -0
  190. package/transitions/types.d.ts +73 -0
  191. package/transitions/useReducedMotion.d.mts +14 -0
  192. package/transitions/useReducedMotion.d.ts +14 -0
  193. package/transitions/useReducedMotion.js +117 -0
  194. package/transitions/useReducedMotion.mjs +110 -0
  195. package/transitions/utils.d.mts +34 -2
  196. package/transitions/utils.d.ts +34 -2
  197. package/transitions/utils.js +33 -4
  198. package/transitions/utils.mjs +31 -4
  199. package/useAutocomplete/useAutocomplete.d.mts +8 -1
  200. package/useAutocomplete/useAutocomplete.d.ts +8 -1
  201. package/useAutocomplete/useAutocomplete.js +66 -4
  202. package/useAutocomplete/useAutocomplete.mjs +66 -4
  203. package/version/index.js +3 -3
  204. package/version/index.mjs +3 -3
  205. /package/transitions/{transition.js → types.js} +0 -0
  206. /package/transitions/{transition.mjs → types.mjs} +0 -0
@@ -164,17 +164,51 @@ function FocusTrap(props) {
164
164
  if (disableEnforceFocus || !isEnabled() || nativeEvent.key !== 'Tab') {
165
165
  return;
166
166
  }
167
+ const rootElement = rootRef.current;
167
168
  const activeElement = (0, _getActiveElement.default)(doc);
169
+ if (rootElement === null) {
170
+ return;
171
+ }
172
+ const focusTarget = (0, _focusable.getFocusTarget)(rootElement);
173
+ const isFocusStart = activeElement === rootElement || activeElement === focusTarget;
168
174
 
169
- // Make sure the next tab starts from the right place.
170
- // activeElement refers to the origin.
171
- if (activeElement === rootRef.current && nativeEvent.shiftKey) {
172
- // We need to ignore the next contain as
173
- // it will try to move the focus back to the rootRef element.
174
- ignoreNextEnforceFocus.current = true;
175
- if (sentinelEnd.current) {
176
- sentinelEnd.current.focus();
175
+ // Marked focus targets can be non-tabbable, but should start tabbing
176
+ // from the first/last tabbable child.
177
+ if (isFocusStart) {
178
+ const tabbable = getTabbable(rootElement);
179
+ if (tabbable.length === 0) {
180
+ return;
181
+ }
182
+ nativeEvent.preventDefault();
183
+ if (nativeEvent.shiftKey) {
184
+ tabbable[tabbable.length - 1].focus();
185
+ } else {
186
+ tabbable[0].focus();
187
+ }
188
+ return;
189
+ }
190
+ if ((0, _contains.default)(rootElement, activeElement)) {
191
+ const tabbable = getTabbable(rootElement);
192
+ const currentIndex = tabbable.indexOf(activeElement);
193
+ if (currentIndex === -1) {
194
+ // Leave shadow-root descendants to native tab handling.
195
+ return;
196
+ }
197
+ const hasPositiveTabIndex = tabbable.some(node => getTabIndex(node) > 0);
198
+
199
+ // Positive tabIndex needs the computed order; regular tabIndex=0 can
200
+ // use native tab handling.
201
+ if (!hasPositiveTabIndex) {
202
+ return;
203
+ }
204
+ nativeEvent.preventDefault();
205
+ let nextIndex = 0;
206
+ if (nativeEvent.shiftKey) {
207
+ nextIndex = currentIndex <= 0 ? tabbable.length - 1 : currentIndex - 1;
208
+ } else {
209
+ nextIndex = currentIndex === tabbable.length - 1 ? 0 : currentIndex + 1;
177
210
  }
211
+ tabbable[nextIndex].focus();
178
212
  }
179
213
  };
180
214
  const contain = () => {
@@ -157,17 +157,51 @@ function FocusTrap(props) {
157
157
  if (disableEnforceFocus || !isEnabled() || nativeEvent.key !== 'Tab') {
158
158
  return;
159
159
  }
160
+ const rootElement = rootRef.current;
160
161
  const activeElement = getActiveElement(doc);
162
+ if (rootElement === null) {
163
+ return;
164
+ }
165
+ const focusTarget = getFocusTarget(rootElement);
166
+ const isFocusStart = activeElement === rootElement || activeElement === focusTarget;
161
167
 
162
- // Make sure the next tab starts from the right place.
163
- // activeElement refers to the origin.
164
- if (activeElement === rootRef.current && nativeEvent.shiftKey) {
165
- // We need to ignore the next contain as
166
- // it will try to move the focus back to the rootRef element.
167
- ignoreNextEnforceFocus.current = true;
168
- if (sentinelEnd.current) {
169
- 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;
170
203
  }
204
+ tabbable[nextIndex].focus();
171
205
  }
172
206
  };
173
207
  const contain = () => {
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.1
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.1
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 };