@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
@@ -0,0 +1,436 @@
1
+ /// <reference path="./react-transition-group.d.ts" />
2
+ 'use client';
3
+
4
+ import * as React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
7
+ import useValueAsRef from '@mui/utils/useValueAsRef';
8
+ // Material UI transitions must still work inside react-transition-group's TransitionGroup.
9
+ // Import only its context module; do not import its Transition or TransitionGroup components.
10
+ import TransitionGroupContext from 'react-transition-group/TransitionGroupContext';
11
+ import { reflow } from "../transitions/utils.mjs";
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ function resolveTimeouts(timeout) {
14
+ if (timeout == null) {
15
+ return {
16
+ appear: undefined,
17
+ enter: undefined,
18
+ exit: undefined
19
+ };
20
+ }
21
+ if (typeof timeout === 'number') {
22
+ return {
23
+ appear: timeout,
24
+ enter: timeout,
25
+ exit: timeout
26
+ };
27
+ }
28
+ const enter = timeout.enter;
29
+ const exit = timeout.exit;
30
+ const appear = timeout.appear !== undefined ? timeout.appear : enter;
31
+ return {
32
+ appear,
33
+ enter,
34
+ exit
35
+ };
36
+ }
37
+
38
+ /**
39
+ * Resolves the authored completion timeout for the current transition phase.
40
+ * Auto durations are read by the caller at scheduling time so Grow/Collapse
41
+ * can pass the latest measured value without storing it in React state.
42
+ */
43
+ function getCompletionTimeout(params) {
44
+ if (params.autoTimeout != null) {
45
+ return params.autoTimeout;
46
+ }
47
+ const resolved = resolveTimeouts(params.timeout);
48
+ if (params.currentStatus === 'entering') {
49
+ return params.isAppearing ? resolved.appear ?? resolved.enter ?? null : resolved.enter ?? null;
50
+ }
51
+ return resolved.exit ?? null;
52
+ }
53
+ function Transition(props) {
54
+ const {
55
+ in: inProp = false,
56
+ appear = false,
57
+ enter = true,
58
+ exit = true,
59
+ mountOnEnter = false,
60
+ unmountOnExit = false,
61
+ timeout,
62
+ addEndListener,
63
+ reduceMotion = false,
64
+ getAutoTimeout,
65
+ nodeRef,
66
+ onEnter,
67
+ onEntering,
68
+ onEntered,
69
+ onExit,
70
+ onExiting,
71
+ onExited,
72
+ children,
73
+ ...childProps
74
+ } = props;
75
+ const parentGroup = React.useContext(TransitionGroupContext);
76
+
77
+ // react-transition-group's TransitionGroup tells children whether the group
78
+ // is still mounting. Material UI needs two values from that:
79
+ // - shouldEnterOnMount: whether this child should run an enter animation now.
80
+ // - isAppearing: the value passed to enter callbacks.
81
+ // A child added after the group mounted still enters, but callbacks receive
82
+ // isAppearing=false because the parent group is no longer mounting.
83
+ const shouldEnterOnMount = parentGroup && !parentGroup.isMounting ? enter : appear;
84
+ const [status, setStatus] = React.useState(() => {
85
+ if (inProp) {
86
+ return shouldEnterOnMount ? 'exited' : 'entered';
87
+ }
88
+ if (mountOnEnter || unmountOnExit) {
89
+ return 'unmounted';
90
+ }
91
+ return 'exited';
92
+ });
93
+ const statusRef = React.useRef(status);
94
+ statusRef.current = status;
95
+ const shouldAppearOnMountRef = React.useRef(inProp && shouldEnterOnMount);
96
+ const mountedRef = React.useRef(false);
97
+ const nextCallbackRef = React.useRef(null);
98
+ // Remember which status already fired lifecycle callbacks. React StrictMode
99
+ // can run effects twice in development; this prevents duplicate callbacks.
100
+ const lastFiredStatusRef = React.useRef(status);
101
+ // Store the isAppearing value for the current enter transition. performEnter
102
+ // sets it before the status effect later calls onEntering/onEntered.
103
+ const isAppearingRef = React.useRef(false);
104
+ // Capture reduced motion at the start of each phase so prop updates do not
105
+ // change the completion timing for an active transition.
106
+ const transitionReduceMotionRef = React.useRef(reduceMotion);
107
+
108
+ // Transition end callbacks can run after props changed. Read props through
109
+ // this ref so delayed work uses the latest callbacks and timeout settings.
110
+ const propsRef = useValueAsRef({
111
+ timeout,
112
+ addEndListener,
113
+ reduceMotion,
114
+ getAutoTimeout,
115
+ onEnter,
116
+ onEntering,
117
+ onEntered,
118
+ onExit,
119
+ onExiting,
120
+ onExited,
121
+ enter,
122
+ exit,
123
+ mountOnEnter,
124
+ unmountOnExit,
125
+ nodeRef,
126
+ parentGroup
127
+ });
128
+
129
+ // Effects below depend on these helpers. Keep their identity stable; they read
130
+ // changing props through propsRef.
131
+ const cancelPendingCallback = React.useCallback(() => {
132
+ if (nextCallbackRef.current !== null) {
133
+ nextCallbackRef.current.cancel();
134
+ nextCallbackRef.current = null;
135
+ }
136
+ }, []);
137
+ const makeCallback = React.useCallback(handler => {
138
+ let active = true;
139
+ const wrapped = () => {
140
+ if (active) {
141
+ active = false;
142
+ nextCallbackRef.current = null;
143
+ handler();
144
+ }
145
+ };
146
+ wrapped.cancel = () => {
147
+ active = false;
148
+ };
149
+ nextCallbackRef.current = wrapped;
150
+ return wrapped;
151
+ }, []);
152
+ const scheduleTransitionEnd = React.useCallback((nextStatus, currentStatus) => {
153
+ let timeoutId;
154
+ const clearTimer = () => {
155
+ if (timeoutId !== undefined) {
156
+ clearTimeout(timeoutId);
157
+ timeoutId = undefined;
158
+ }
159
+ };
160
+ const done = makeCallback(() => {
161
+ clearTimer();
162
+ statusRef.current = nextStatus;
163
+ setStatus(nextStatus);
164
+ });
165
+ const cancelDone = done.cancel;
166
+ done.cancel = () => {
167
+ clearTimer();
168
+ cancelDone();
169
+ };
170
+ const node = propsRef.current.nodeRef.current;
171
+ const listener = propsRef.current.addEndListener;
172
+ const hasAutoTimeout = propsRef.current.getAutoTimeout !== undefined;
173
+ const autoTimeout = propsRef.current.getAutoTimeout?.();
174
+ const authoredTimeout = getCompletionTimeout({
175
+ currentStatus,
176
+ isAppearing: isAppearingRef.current,
177
+ timeout: propsRef.current.timeout,
178
+ autoTimeout
179
+ });
180
+ const transitionReduceMotion = transitionReduceMotionRef.current;
181
+ // Auto-duration consumers may skip measurement under reduced motion, but
182
+ // still need a 0ms timeout when they provide addEndListener.
183
+ const fallbackTimeout = authoredTimeout ?? (transitionReduceMotion && hasAutoTimeout ? 0 : null);
184
+ const scheduleTimer = value => {
185
+ timeoutId = setTimeout(done, value);
186
+ };
187
+ if (!node) {
188
+ if (process.env.NODE_ENV !== 'production') {
189
+ console.warn(['MUI: The transition child does not expose a DOM element.', 'Make sure the child accepts a ref and forwards it to the underlying DOM element.', 'The transition animation cannot be observed without a DOM element and will be skipped.'].join('\n'));
190
+ }
191
+
192
+ // Match react-transition-group: if there is no DOM node, there is no
193
+ // transition to observe, so finish on the next tick.
194
+ scheduleTimer(0);
195
+ return;
196
+ }
197
+ if (listener) {
198
+ if (fallbackTimeout != null) {
199
+ scheduleTimer(transitionReduceMotion ? 0 : fallbackTimeout);
200
+ }
201
+
202
+ // With nodeRef, react-transition-group calls addEndListener(done).
203
+ // Material UI has long supported addEndListener(node, done). Keep both call
204
+ // shapes so existing transition wrappers do not have to change.
205
+ if (listener.length >= 2) {
206
+ listener(node, done);
207
+ } else {
208
+ listener(done);
209
+ }
210
+ return;
211
+ }
212
+ scheduleTimer(transitionReduceMotion ? 0 : authoredTimeout ?? 0);
213
+ }, [makeCallback, propsRef]);
214
+ const performEnter = React.useCallback(mounting => {
215
+ const current = propsRef.current;
216
+ const isAppearing = current.parentGroup ? current.parentGroup.isMounting : mounting;
217
+ isAppearingRef.current = isAppearing;
218
+
219
+ // On updates, enter=false skips the enter animation. Move straight to
220
+ // entered; the status effect will call onEntered, but onEnter/onEntering
221
+ // must not fire.
222
+ if (!mounting && !current.enter) {
223
+ statusRef.current = 'entered';
224
+ setStatus('entered');
225
+ return;
226
+ }
227
+ transitionReduceMotionRef.current = current.reduceMotion;
228
+ current.onEnter?.(isAppearing);
229
+ statusRef.current = 'entering';
230
+ setStatus('entering');
231
+ }, [propsRef]);
232
+ const performExit = React.useCallback(() => {
233
+ const current = propsRef.current;
234
+ if (!current.exit) {
235
+ statusRef.current = 'exited';
236
+ setStatus('exited');
237
+ return;
238
+ }
239
+ transitionReduceMotionRef.current = current.reduceMotion;
240
+ current.onExit?.();
241
+ statusRef.current = 'exiting';
242
+ setStatus('exiting');
243
+ }, [propsRef]);
244
+ const updateStatus = React.useCallback((mounting, nextStatus) => {
245
+ cancelPendingCallback();
246
+ if (nextStatus === 'entering') {
247
+ const current = propsRef.current;
248
+ // If the node was just mounted, read layout before entering so the
249
+ // browser applies the starting styles before the animation begins.
250
+ if (current.mountOnEnter || current.unmountOnExit) {
251
+ const node = current.nodeRef.current;
252
+ if (node) {
253
+ reflow(node);
254
+ }
255
+ }
256
+ performEnter(mounting);
257
+ } else {
258
+ performExit();
259
+ }
260
+ }, [cancelPendingCallback, performEnter, performExit, propsRef]);
261
+
262
+ // Runs on mount. useEnhancedEffect is needed because the initial appear
263
+ // transition may read layout before paint. In StrictMode development builds,
264
+ // React mounts, cleans up, and mounts again; cleanup cancels pending work and
265
+ // the second mount restarts the same transition.
266
+ useEnhancedEffect(() => {
267
+ mountedRef.current = true;
268
+ if (shouldAppearOnMountRef.current) {
269
+ shouldAppearOnMountRef.current = false;
270
+ updateStatus(true, 'entering');
271
+ }
272
+ return () => {
273
+ mountedRef.current = false;
274
+ cancelPendingCallback();
275
+ };
276
+ }, [cancelPendingCallback, updateStatus]);
277
+
278
+ // Reconcile the rendered status after `in` or status changes:
279
+ // - opening from unmounted first renders the child as exited so refs exist.
280
+ // - unmountOnExit removes the child after the exited state commits.
281
+ // This matches react-transition-group's observable status steps without
282
+ // running work after unrelated commits.
283
+ useEnhancedEffect(() => {
284
+ if (!mountedRef.current) {
285
+ return;
286
+ }
287
+ const current = statusRef.current;
288
+ if (inProp) {
289
+ if (current === 'unmounted') {
290
+ // Opening from unmounted needs one render with the child present so
291
+ // refs are attached before the enter animation starts.
292
+ statusRef.current = 'exited';
293
+ setStatus('exited');
294
+ } else if (current !== 'entering' && current !== 'entered') {
295
+ updateStatus(false, 'entering');
296
+ }
297
+ } else if (current === 'entering' || current === 'entered') {
298
+ updateStatus(false, 'exiting');
299
+ } else if (current === 'exited' && unmountOnExit) {
300
+ statusRef.current = 'unmounted';
301
+ setStatus('unmounted');
302
+ }
303
+ }, [inProp, status, unmountOnExit, updateStatus]);
304
+
305
+ // Fire lifecycle callbacks for committed status changes. The guard prevents
306
+ // duplicate callbacks in StrictMode; propsRef keeps delayed callbacks fresh.
307
+ useEnhancedEffect(() => {
308
+ // `unmounted` is bookkeeping, not a real transition state. Do not fire
309
+ // callbacks when moving into or out of it; otherwise the first open with
310
+ // mountOnEnter/unmountOnExit would look like a completed exit.
311
+ if (status === 'unmounted' || lastFiredStatusRef.current === 'unmounted') {
312
+ lastFiredStatusRef.current = status;
313
+ return;
314
+ }
315
+ const prev = lastFiredStatusRef.current;
316
+ if (prev === status) {
317
+ return;
318
+ }
319
+ lastFiredStatusRef.current = status;
320
+ const current = propsRef.current;
321
+ if (status === 'entering') {
322
+ current.onEntering?.(isAppearingRef.current);
323
+ scheduleTransitionEnd('entered', 'entering');
324
+ } else if (status === 'exiting') {
325
+ current.onExiting?.();
326
+ scheduleTransitionEnd('exited', 'exiting');
327
+ } else if (status === 'entered') {
328
+ current.onEntered?.(isAppearingRef.current);
329
+ } else if (status === 'exited') {
330
+ current.onExited?.();
331
+ }
332
+ }, [propsRef, scheduleTransitionEnd, status]);
333
+ if (status === 'unmounted') {
334
+ return null;
335
+ }
336
+
337
+ // Nested Material UI transitions should not inherit this transition's parent group.
338
+ // A null context keeps an outer TransitionGroup from controlling them.
339
+ return /*#__PURE__*/_jsx(TransitionGroupContext.Provider, {
340
+ value: null,
341
+ children: children(status, childProps)
342
+ });
343
+ }
344
+ process.env.NODE_ENV !== "production" ? Transition.propTypes /* remove-proptypes */ = {
345
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
346
+ // │ These PropTypes are generated from the TypeScript type definitions. │
347
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
348
+ // └─────────────────────────────────────────────────────────────────────┘
349
+ /**
350
+ * @ignore
351
+ */
352
+ addEndListener: PropTypes.func,
353
+ /**
354
+ * @ignore
355
+ */
356
+ appear: PropTypes.bool,
357
+ /**
358
+ * @ignore
359
+ */
360
+ children: PropTypes.func.isRequired,
361
+ /**
362
+ * @ignore
363
+ */
364
+ enter: PropTypes.bool,
365
+ /**
366
+ * @ignore
367
+ */
368
+ exit: PropTypes.bool,
369
+ /**
370
+ * @ignore
371
+ */
372
+ getAutoTimeout: PropTypes.func,
373
+ /**
374
+ * @ignore
375
+ */
376
+ in: PropTypes.bool,
377
+ /**
378
+ * @ignore
379
+ */
380
+ mountOnEnter: PropTypes.bool,
381
+ /**
382
+ * @ignore
383
+ */
384
+ nodeRef: PropTypes.shape({
385
+ current: (props, propName) => {
386
+ if (props[propName] == null) {
387
+ return null;
388
+ }
389
+ if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) {
390
+ return new Error(`Expected prop '${propName}' to be of type Element`);
391
+ }
392
+ return null;
393
+ }
394
+ }).isRequired,
395
+ /**
396
+ * @ignore
397
+ */
398
+ onEnter: PropTypes.func,
399
+ /**
400
+ * @ignore
401
+ */
402
+ onEntered: PropTypes.func,
403
+ /**
404
+ * @ignore
405
+ */
406
+ onEntering: PropTypes.func,
407
+ /**
408
+ * @ignore
409
+ */
410
+ onExit: PropTypes.func,
411
+ /**
412
+ * @ignore
413
+ */
414
+ onExited: PropTypes.func,
415
+ /**
416
+ * @ignore
417
+ */
418
+ onExiting: PropTypes.func,
419
+ /**
420
+ * @ignore
421
+ */
422
+ reduceMotion: PropTypes.bool,
423
+ /**
424
+ * @ignore
425
+ */
426
+ timeout: PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
427
+ appear: PropTypes.number,
428
+ enter: PropTypes.number,
429
+ exit: PropTypes.number
430
+ })]),
431
+ /**
432
+ * @ignore
433
+ */
434
+ unmountOnExit: PropTypes.bool
435
+ } : void 0;
436
+ export default Transition;
@@ -0,0 +1,8 @@
1
+ declare module 'react-transition-group/TransitionGroupContext' {
2
+ import * as React from 'react';
3
+ interface TransitionGroupContextValue {
4
+ isMounting: boolean;
5
+ }
6
+ const TransitionGroupContext: React.Context<TransitionGroupContextValue | null>;
7
+ export default TransitionGroupContext;
8
+ }
@@ -0,0 +1,8 @@
1
+ declare module 'react-transition-group/TransitionGroupContext' {
2
+ import * as React from 'react';
3
+ interface TransitionGroupContextValue {
4
+ isMounting: boolean;
5
+ }
6
+ const TransitionGroupContext: React.Context<TransitionGroupContextValue | null>;
7
+ export default TransitionGroupContext;
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/material",
3
- "version": "9.0.1",
3
+ "version": "9.1.0",
4
4
  "author": "MUI Team",
5
5
  "description": "Material UI is an open-source React component library that implements Google's Material Design. It's comprehensive and can be used in production out of the box.",
6
6
  "license": "MIT",
@@ -31,12 +31,12 @@
31
31
  "clsx": "^2.1.1",
32
32
  "csstype": "^3.2.3",
33
33
  "prop-types": "^15.8.1",
34
- "react-is": "^19.2.4",
34
+ "react-is": "^19.2.6",
35
35
  "react-transition-group": "^4.4.5",
36
- "@mui/core-downloads-tracker": "^9.0.1",
37
- "@mui/system": "^9.0.1",
36
+ "@mui/core-downloads-tracker": "^9.1.0",
38
37
  "@mui/types": "^9.0.0",
39
- "@mui/utils": "^9.0.1"
38
+ "@mui/utils": "^9.1.0",
39
+ "@mui/system": "^9.1.0"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@emotion/react": "^11.5.0",
@@ -44,7 +44,7 @@
44
44
  "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
45
45
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
46
46
  "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0",
47
- "@mui/material-pigment-css": "^9.0.1"
47
+ "@mui/material-pigment-css": "^9.1.0"
48
48
  },
49
49
  "peerDependenciesMeta": {
50
50
  "@types/react": {
@@ -0,0 +1,8 @@
1
+ export type ReducedMotionMode = 'never' | 'system' | 'always';
2
+ export interface Motion {
3
+ reducedMotion: ReducedMotionMode;
4
+ }
5
+ export interface MotionOptions {
6
+ reducedMotion?: ReducedMotionMode | undefined;
7
+ }
8
+ export default function createMotion(inputMotion?: MotionOptions): Motion;
@@ -0,0 +1,8 @@
1
+ export type ReducedMotionMode = 'never' | 'system' | 'always';
2
+ export interface Motion {
3
+ reducedMotion: ReducedMotionMode;
4
+ }
5
+ export interface MotionOptions {
6
+ reducedMotion?: ReducedMotionMode | undefined;
7
+ }
8
+ export default function createMotion(inputMotion?: MotionOptions): Motion;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = createMotion;
7
+ const EMPTY_MOTION = {};
8
+ function createMotion(inputMotion = EMPTY_MOTION) {
9
+ return {
10
+ reducedMotion: 'never',
11
+ ...inputMotion
12
+ };
13
+ }
@@ -0,0 +1,7 @@
1
+ const EMPTY_MOTION = {};
2
+ export default function createMotion(inputMotion = EMPTY_MOTION) {
3
+ return {
4
+ reducedMotion: 'never',
5
+ ...inputMotion
6
+ };
7
+ }
@@ -3,6 +3,7 @@ import { SxConfig, SxProps, CSSObject, ApplyStyles, Theme as SystemTheme, Shape
3
3
  import { ExtractTypographyTokens } from '@mui/system/cssVars';
4
4
  import { Palette, PaletteOptions } from "./createPalette.mjs";
5
5
  import { Shadows } from "./shadows.mjs";
6
+ import { Motion } from "./createMotion.mjs";
6
7
  import { Transitions } from "./createTransitions.mjs";
7
8
  import { Mixins } from "./createMixins.mjs";
8
9
  import { TypographyVariants } from "./createTypography.mjs";
@@ -260,6 +261,7 @@ export interface CssVarsTheme extends ColorSystem {
260
261
  breakpoints: SystemTheme['breakpoints'];
261
262
  shape: Shape;
262
263
  typography: TypographyVariants;
264
+ motion: Motion;
263
265
  transitions: Transitions;
264
266
  shadows: Shadows;
265
267
  mixins: Mixins;
@@ -3,6 +3,7 @@ import { SxConfig, SxProps, CSSObject, ApplyStyles, Theme as SystemTheme, Shape
3
3
  import { ExtractTypographyTokens } from '@mui/system/cssVars';
4
4
  import { Palette, PaletteOptions } from "./createPalette.js";
5
5
  import { Shadows } from "./shadows.js";
6
+ import { Motion } from "./createMotion.js";
6
7
  import { Transitions } from "./createTransitions.js";
7
8
  import { Mixins } from "./createMixins.js";
8
9
  import { TypographyVariants } from "./createTypography.js";
@@ -260,6 +261,7 @@ export interface CssVarsTheme extends ColorSystem {
260
261
  breakpoints: SystemTheme['breakpoints'];
261
262
  shape: Shape;
262
263
  typography: TypographyVariants;
264
+ motion: Motion;
263
265
  transitions: Transitions;
264
266
  shadows: Shadows;
265
267
  mixins: Mixins;
@@ -3,6 +3,7 @@ import { Mixins, MixinsOptions } from "./createMixins.mjs";
3
3
  import { Palette, PaletteOptions } from "./createPalette.mjs";
4
4
  import { TypographyVariants, TypographyVariantsOptions } from "./createTypography.mjs";
5
5
  import { Shadows } from "./shadows.mjs";
6
+ import { Motion, MotionOptions } from "./createMotion.mjs";
6
7
  import { Transitions, TransitionsOptions } from "./createTransitions.mjs";
7
8
  import { ZIndex, ZIndexOptions } from "./zIndex.mjs";
8
9
  import { Components } from "./components.mjs";
@@ -25,6 +26,7 @@ type CssVarsOptions = CssThemeVariables extends {
25
26
  export interface ThemeOptions extends Omit<SystemThemeOptions, 'zIndex'>, CssVarsOptions {
26
27
  mixins?: MixinsOptions | undefined;
27
28
  components?: Components<Omit<Theme, 'components'>> | undefined;
29
+ motion?: MotionOptions | undefined;
28
30
  palette?: PaletteOptions | undefined;
29
31
  shadows?: Shadows | undefined;
30
32
  shape?: ShapeOptions | undefined;
@@ -37,6 +39,7 @@ export interface ThemeOptions extends Omit<SystemThemeOptions, 'zIndex'>, CssVar
37
39
  }
38
40
  export interface BaseTheme extends SystemTheme {
39
41
  mixins: Mixins;
42
+ motion: Motion;
40
43
  palette: Palette & (CssThemeVariables extends {
41
44
  enabled: true;
42
45
  } ? CssVarsPalette : {});
@@ -3,6 +3,7 @@ import { Mixins, MixinsOptions } from "./createMixins.js";
3
3
  import { Palette, PaletteOptions } from "./createPalette.js";
4
4
  import { TypographyVariants, TypographyVariantsOptions } from "./createTypography.js";
5
5
  import { Shadows } from "./shadows.js";
6
+ import { Motion, MotionOptions } from "./createMotion.js";
6
7
  import { Transitions, TransitionsOptions } from "./createTransitions.js";
7
8
  import { ZIndex, ZIndexOptions } from "./zIndex.js";
8
9
  import { Components } from "./components.js";
@@ -25,6 +26,7 @@ type CssVarsOptions = CssThemeVariables extends {
25
26
  export interface ThemeOptions extends Omit<SystemThemeOptions, 'zIndex'>, CssVarsOptions {
26
27
  mixins?: MixinsOptions | undefined;
27
28
  components?: Components<Omit<Theme, 'components'>> | undefined;
29
+ motion?: MotionOptions | undefined;
28
30
  palette?: PaletteOptions | undefined;
29
31
  shadows?: Shadows | undefined;
30
32
  shape?: ShapeOptions | undefined;
@@ -37,6 +39,7 @@ export interface ThemeOptions extends Omit<SystemThemeOptions, 'zIndex'>, CssVar
37
39
  }
38
40
  export interface BaseTheme extends SystemTheme {
39
41
  mixins: Mixins;
42
+ motion: Motion;
40
43
  palette: Palette & (CssThemeVariables extends {
41
44
  enabled: true;
42
45
  } ? CssVarsPalette : {});
@@ -17,6 +17,7 @@ var _createPalette = _interopRequireDefault(require("./createPalette"));
17
17
  var _createTypography = _interopRequireDefault(require("./createTypography"));
18
18
  var _shadows = _interopRequireDefault(require("./shadows"));
19
19
  var _createTransitions = _interopRequireDefault(require("./createTransitions"));
20
+ var _createMotion = _interopRequireDefault(require("./createMotion"));
20
21
  var _zIndex = _interopRequireDefault(require("./zIndex"));
21
22
  var _stringifyTheme = require("./stringifyTheme");
22
23
  function coefficientToPercentage(coefficient) {
@@ -77,6 +78,7 @@ function createThemeNoVars(options = {}, ...args) {
77
78
  mixins: mixinsInput = {},
78
79
  spacing: spacingInput,
79
80
  palette: paletteInput = {},
81
+ motion: motionInput = {},
80
82
  transitions: transitionsInput = {},
81
83
  typography: typographyInput = {},
82
84
  shape: shapeInput,
@@ -102,6 +104,7 @@ function createThemeNoVars(options = {}, ...args) {
102
104
  // Don't use [...shadows] until you've verified its transpiled code is not invoking the iterator protocol.
103
105
  shadows: _shadows.default.slice(),
104
106
  typography: (0, _createTypography.default)(palette, typographyInput),
107
+ motion: (0, _createMotion.default)(motionInput),
105
108
  transitions: (0, _createTransitions.default)(transitionsInput),
106
109
  zIndex: {
107
110
  ..._zIndex.default
@@ -109,6 +112,8 @@ function createThemeNoVars(options = {}, ...args) {
109
112
  });
110
113
  muiTheme = (0, _deepmerge.default)(muiTheme, other);
111
114
  muiTheme = args.reduce((acc, argument) => (0, _deepmerge.default)(acc, argument), muiTheme);
115
+ // `reducedMotion` is owned by `theme.motion`; remove stale values preserved by systemCreateTheme.
116
+ delete muiTheme.transitions.reducedMotion;
112
117
  if (process.env.NODE_ENV !== 'production') {
113
118
  // TODO v6: Refactor to use globalStateClassesMapping from @mui/utils once `readOnly` state class is used in Rating component.
114
119
  const stateClasses = ['active', 'checked', 'completed', 'disabled', 'error', 'expanded', 'focused', 'focusVisible', 'required', 'selected'];
@@ -9,6 +9,7 @@ import createPalette from "./createPalette.mjs";
9
9
  import createTypography from "./createTypography.mjs";
10
10
  import shadows from "./shadows.mjs";
11
11
  import createTransitions from "./createTransitions.mjs";
12
+ import createMotion from "./createMotion.mjs";
12
13
  import zIndex from "./zIndex.mjs";
13
14
  import { stringifyTheme } from "./stringifyTheme.mjs";
14
15
  function coefficientToPercentage(coefficient) {
@@ -69,6 +70,7 @@ function createThemeNoVars(options = {}, ...args) {
69
70
  mixins: mixinsInput = {},
70
71
  spacing: spacingInput,
71
72
  palette: paletteInput = {},
73
+ motion: motionInput = {},
72
74
  transitions: transitionsInput = {},
73
75
  typography: typographyInput = {},
74
76
  shape: shapeInput,
@@ -94,6 +96,7 @@ function createThemeNoVars(options = {}, ...args) {
94
96
  // Don't use [...shadows] until you've verified its transpiled code is not invoking the iterator protocol.
95
97
  shadows: shadows.slice(),
96
98
  typography: createTypography(palette, typographyInput),
99
+ motion: createMotion(motionInput),
97
100
  transitions: createTransitions(transitionsInput),
98
101
  zIndex: {
99
102
  ...zIndex
@@ -101,6 +104,8 @@ function createThemeNoVars(options = {}, ...args) {
101
104
  });
102
105
  muiTheme = deepmerge(muiTheme, other);
103
106
  muiTheme = args.reduce((acc, argument) => deepmerge(acc, argument), muiTheme);
107
+ // `reducedMotion` is owned by `theme.motion`; remove stale values preserved by systemCreateTheme.
108
+ delete muiTheme.transitions.reducedMotion;
104
109
  if (process.env.NODE_ENV !== 'production') {
105
110
  // TODO v6: Refactor to use globalStateClassesMapping from @mui/utils once `readOnly` state class is used in Rating component.
106
111
  const stateClasses = ['active', 'checked', 'completed', 'disabled', 'error', 'expanded', 'focused', 'focusVisible', 'required', 'selected'];