@mui/material 9.0.1 → 9.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) 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.d.mts +5 -1
  8. package/Autocomplete/Autocomplete.d.ts +5 -1
  9. package/Autocomplete/Autocomplete.js +13 -7
  10. package/Autocomplete/Autocomplete.mjs +13 -7
  11. package/Backdrop/Backdrop.d.mts +2 -2
  12. package/Backdrop/Backdrop.d.ts +2 -2
  13. package/Badge/Badge.js +28 -24
  14. package/Badge/Badge.mjs +28 -24
  15. package/BottomNavigationAction/BottomNavigationAction.js +6 -2
  16. package/BottomNavigationAction/BottomNavigationAction.mjs +6 -2
  17. package/Button/Button.js +11 -15
  18. package/Button/Button.mjs +11 -15
  19. package/ButtonBase/Ripple.js +21 -11
  20. package/ButtonBase/Ripple.mjs +21 -11
  21. package/ButtonBase/TouchRipple.js +252 -108
  22. package/ButtonBase/TouchRipple.mjs +253 -109
  23. package/CHANGELOG.md +122 -0
  24. package/CardActionArea/CardActionArea.js +2 -1
  25. package/CardActionArea/CardActionArea.mjs +2 -1
  26. package/Chip/Chip.js +2 -1
  27. package/Chip/Chip.mjs +2 -1
  28. package/CircularProgress/CircularProgress.js +85 -55
  29. package/CircularProgress/CircularProgress.mjs +84 -55
  30. package/Collapse/Collapse.d.mts +15 -3
  31. package/Collapse/Collapse.d.ts +15 -3
  32. package/Collapse/Collapse.js +44 -31
  33. package/Collapse/Collapse.mjs +43 -30
  34. package/Dialog/Dialog.d.mts +2 -2
  35. package/Dialog/Dialog.d.ts +2 -2
  36. package/Dialog/Dialog.js +2 -0
  37. package/Dialog/Dialog.mjs +2 -0
  38. package/Drawer/Drawer.d.mts +2 -2
  39. package/Drawer/Drawer.d.ts +2 -2
  40. package/Fab/Fab.js +2 -1
  41. package/Fab/Fab.mjs +2 -1
  42. package/Fade/Fade.d.mts +15 -2
  43. package/Fade/Fade.d.ts +15 -2
  44. package/Fade/Fade.js +46 -19
  45. package/Fade/Fade.mjs +45 -18
  46. package/FilledInput/FilledInput.js +4 -3
  47. package/FilledInput/FilledInput.mjs +4 -3
  48. package/Grow/Grow.d.mts +15 -2
  49. package/Grow/Grow.d.ts +15 -2
  50. package/Grow/Grow.js +45 -28
  51. package/Grow/Grow.mjs +44 -27
  52. package/IconButton/IconButton.js +2 -1
  53. package/IconButton/IconButton.mjs +2 -1
  54. package/InitColorSchemeScript/InitColorSchemeScript.d.mts +5 -5
  55. package/InitColorSchemeScript/InitColorSchemeScript.d.ts +5 -5
  56. package/Input/Input.js +3 -2
  57. package/Input/Input.mjs +3 -2
  58. package/InputBase/InputBase.js +2 -1
  59. package/InputBase/InputBase.mjs +2 -1
  60. package/InputLabel/InputLabel.js +2 -1
  61. package/InputLabel/InputLabel.mjs +2 -1
  62. package/LICENSE +1 -1
  63. package/LinearProgress/LinearProgress.js +187 -120
  64. package/LinearProgress/LinearProgress.mjs +186 -120
  65. package/ListItem/ListItem.js +2 -1
  66. package/ListItem/ListItem.mjs +2 -1
  67. package/ListItemButton/ListItemButton.js +2 -1
  68. package/ListItemButton/ListItemButton.mjs +2 -1
  69. package/Menu/Menu.d.mts +1 -1
  70. package/Menu/Menu.d.ts +1 -1
  71. package/MobileStepper/MobileStepper.js +2 -1
  72. package/MobileStepper/MobileStepper.mjs +2 -1
  73. package/OutlinedInput/NotchedOutline.js +4 -3
  74. package/OutlinedInput/NotchedOutline.mjs +4 -3
  75. package/PaginationItem/PaginationItem.js +2 -1
  76. package/PaginationItem/PaginationItem.mjs +2 -1
  77. package/Paper/Paper.js +2 -1
  78. package/Paper/Paper.mjs +2 -1
  79. package/Popover/Popover.d.mts +1 -1
  80. package/Popover/Popover.d.ts +1 -1
  81. package/README.md +3 -2
  82. package/Radio/RadioButtonIcon.js +3 -2
  83. package/Radio/RadioButtonIcon.mjs +3 -2
  84. package/Rating/Rating.js +2 -1
  85. package/Rating/Rating.mjs +2 -1
  86. package/Select/SelectInput.js +115 -25
  87. package/Select/SelectInput.mjs +115 -25
  88. package/Select/utils/SelectFocusSourceContext.d.mts +2 -2
  89. package/Select/utils/SelectFocusSourceContext.d.ts +2 -2
  90. package/Select/utils/closedTypeahead.js +73 -0
  91. package/Select/utils/closedTypeahead.mjs +63 -0
  92. package/Skeleton/Skeleton.js +22 -2
  93. package/Skeleton/Skeleton.mjs +22 -2
  94. package/Slide/Slide.d.mts +15 -2
  95. package/Slide/Slide.d.ts +15 -2
  96. package/Slide/Slide.js +53 -25
  97. package/Slide/Slide.mjs +52 -24
  98. package/Slider/Slider.js +4 -3
  99. package/Slider/Slider.mjs +4 -3
  100. package/Slider/SliderValueLabel.d.mts +2 -2
  101. package/Slider/SliderValueLabel.d.ts +2 -2
  102. package/Slider/useSlider.js +1 -1
  103. package/Slider/useSlider.mjs +1 -1
  104. package/Snackbar/Snackbar.d.mts +2 -2
  105. package/Snackbar/Snackbar.d.ts +2 -2
  106. package/SpeedDial/SpeedDial.d.mts +1 -1
  107. package/SpeedDial/SpeedDial.d.ts +1 -1
  108. package/SpeedDial/SpeedDial.js +6 -2
  109. package/SpeedDial/SpeedDial.mjs +6 -2
  110. package/SpeedDialAction/SpeedDialAction.js +11 -2
  111. package/SpeedDialAction/SpeedDialAction.mjs +12 -3
  112. package/SpeedDialIcon/SpeedDialIcon.js +40 -37
  113. package/SpeedDialIcon/SpeedDialIcon.mjs +40 -37
  114. package/Step/Step.js +47 -15
  115. package/Step/Step.mjs +47 -15
  116. package/Step/StepContext.d.mts +1 -1
  117. package/Step/StepContext.d.ts +1 -1
  118. package/StepButton/StepButton.js +9 -3
  119. package/StepButton/StepButton.mjs +9 -3
  120. package/StepConnector/StepConnector.js +10 -0
  121. package/StepConnector/StepConnector.mjs +10 -0
  122. package/StepContent/StepContent.d.mts +2 -2
  123. package/StepContent/StepContent.d.ts +2 -2
  124. package/StepContent/StepContent.js +26 -2
  125. package/StepContent/StepContent.mjs +26 -2
  126. package/StepIcon/StepIcon.js +2 -1
  127. package/StepIcon/StepIcon.mjs +2 -1
  128. package/StepLabel/StepLabel.js +52 -7
  129. package/StepLabel/StepLabel.mjs +52 -7
  130. package/Stepper/Stepper.d.mts +2 -0
  131. package/Stepper/Stepper.d.ts +2 -0
  132. package/Stepper/Stepper.js +18 -0
  133. package/Stepper/Stepper.mjs +18 -0
  134. package/Stepper/StepperContext.d.mts +1 -1
  135. package/Stepper/StepperContext.d.ts +1 -1
  136. package/SvgIcon/SvgIcon.js +2 -1
  137. package/SvgIcon/SvgIcon.mjs +2 -1
  138. package/SwipeableDrawer/SwipeableDrawer.js +14 -3
  139. package/SwipeableDrawer/SwipeableDrawer.mjs +14 -3
  140. package/Switch/Switch.js +3 -2
  141. package/Switch/Switch.mjs +3 -2
  142. package/TableSortLabel/TableSortLabel.js +2 -1
  143. package/TableSortLabel/TableSortLabel.mjs +2 -1
  144. package/Tabs/Tabs.js +14 -3
  145. package/Tabs/Tabs.mjs +14 -3
  146. package/Tooltip/Tooltip.d.mts +2 -2
  147. package/Tooltip/Tooltip.d.ts +2 -2
  148. package/Tooltip/Tooltip.js +3 -0
  149. package/Tooltip/Tooltip.mjs +3 -0
  150. package/Unstable_TrapFocus/FocusTrap.js +42 -8
  151. package/Unstable_TrapFocus/FocusTrap.mjs +42 -8
  152. package/Zoom/Zoom.d.mts +15 -2
  153. package/Zoom/Zoom.d.ts +15 -2
  154. package/Zoom/Zoom.js +43 -16
  155. package/Zoom/Zoom.mjs +42 -15
  156. package/index.js +1 -1
  157. package/index.mjs +1 -1
  158. package/internal/Transition.d.mts +34 -0
  159. package/internal/Transition.d.ts +34 -0
  160. package/internal/Transition.js +450 -0
  161. package/internal/Transition.mjs +442 -0
  162. package/internal/react-transition-group.d.mts +8 -0
  163. package/internal/react-transition-group.d.ts +8 -0
  164. package/package.json +7 -7
  165. package/styles/ThemeProviderWithVars.d.mts +7 -7
  166. package/styles/ThemeProviderWithVars.d.ts +7 -7
  167. package/styles/createGetSelector.d.mts +2 -2
  168. package/styles/createGetSelector.d.ts +2 -2
  169. package/styles/createMotion.d.mts +8 -0
  170. package/styles/createMotion.d.ts +8 -0
  171. package/styles/createMotion.js +13 -0
  172. package/styles/createMotion.mjs +7 -0
  173. package/styles/createThemeFoundation.d.mts +2 -0
  174. package/styles/createThemeFoundation.d.ts +2 -0
  175. package/styles/createThemeNoVars.d.mts +3 -0
  176. package/styles/createThemeNoVars.d.ts +3 -0
  177. package/styles/createThemeNoVars.js +5 -0
  178. package/styles/createThemeNoVars.mjs +5 -0
  179. package/styles/createTransitions.d.mts +6 -2
  180. package/styles/createTransitions.d.ts +6 -2
  181. package/styles/createTransitions.js +12 -4
  182. package/styles/createTransitions.mjs +12 -4
  183. package/styles/enhanceHighContrast.d.mts +70 -0
  184. package/styles/enhanceHighContrast.d.ts +70 -0
  185. package/styles/enhanceHighContrast.js +502 -0
  186. package/styles/enhanceHighContrast.mjs +495 -0
  187. package/styles/identifier.d.mts +1 -1
  188. package/styles/identifier.d.ts +1 -1
  189. package/styles/index.d.mts +2 -0
  190. package/styles/index.d.ts +2 -0
  191. package/styles/index.js +8 -0
  192. package/styles/index.mjs +1 -0
  193. package/styles/reducedMotion.d.mts +7 -0
  194. package/styles/reducedMotion.d.ts +7 -0
  195. package/styles/reducedMotion.js +21 -0
  196. package/styles/reducedMotion.mjs +14 -0
  197. package/styles/shouldSkipGeneratingVar.js +1 -1
  198. package/styles/shouldSkipGeneratingVar.mjs +1 -1
  199. package/styles/stringifyTheme.js +1 -0
  200. package/styles/stringifyTheme.mjs +1 -0
  201. package/transitions/index.d.mts +1 -1
  202. package/transitions/index.d.ts +1 -1
  203. package/transitions/index.js +0 -11
  204. package/transitions/index.mjs +1 -1
  205. package/transitions/transition.d.mts +1 -12
  206. package/transitions/transition.d.ts +1 -12
  207. package/transitions/types.d.mts +73 -0
  208. package/transitions/types.d.ts +73 -0
  209. package/transitions/useReducedMotion.d.mts +14 -0
  210. package/transitions/useReducedMotion.d.ts +14 -0
  211. package/transitions/useReducedMotion.js +117 -0
  212. package/transitions/useReducedMotion.mjs +110 -0
  213. package/transitions/utils.d.mts +34 -2
  214. package/transitions/utils.d.ts +34 -2
  215. package/transitions/utils.js +33 -4
  216. package/transitions/utils.mjs +31 -4
  217. package/useAutocomplete/useAutocomplete.d.mts +8 -1
  218. package/useAutocomplete/useAutocomplete.d.ts +8 -1
  219. package/useAutocomplete/useAutocomplete.js +66 -4
  220. package/useAutocomplete/useAutocomplete.mjs +66 -4
  221. package/utils/memoTheme.d.mts +1 -1
  222. package/utils/memoTheme.d.ts +1 -1
  223. package/utils/useSlot.d.mts +1 -1
  224. package/utils/useSlot.d.ts +1 -1
  225. package/version/index.js +2 -2
  226. package/version/index.mjs +2 -2
  227. /package/transitions/{transition.js → types.js} +0 -0
  228. /package/transitions/{transition.mjs → types.mjs} +0 -0
@@ -0,0 +1,442 @@
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
+
96
+ // Opening from `unmounted`: mount the child in the same commit that `in` turns
97
+ // true so its ref is attached before effects run. react-transition-group did
98
+ // this by deriving the status from props during render; handling it in a
99
+ // layout effect instead would add a commit where the child is still null,
100
+ // breaking consumers that read the ref right after `in` flips.
101
+ if (inProp && status === 'unmounted') {
102
+ statusRef.current = 'exited';
103
+ setStatus('exited');
104
+ }
105
+ const shouldAppearOnMountRef = React.useRef(inProp && shouldEnterOnMount);
106
+ const mountedRef = React.useRef(false);
107
+ const nextCallbackRef = React.useRef(null);
108
+ // Remember which status already fired lifecycle callbacks. React StrictMode
109
+ // can run effects twice in development; this prevents duplicate callbacks.
110
+ const lastFiredStatusRef = React.useRef(status);
111
+ // Store the isAppearing value for the current enter transition. performEnter
112
+ // sets it before the status effect later calls onEntering/onEntered.
113
+ const isAppearingRef = React.useRef(false);
114
+ // Capture reduced motion at the start of each phase so prop updates do not
115
+ // change the completion timing for an active transition.
116
+ const transitionReduceMotionRef = React.useRef(reduceMotion);
117
+
118
+ // Transition end callbacks can run after props changed. Read props through
119
+ // this ref so delayed work uses the latest callbacks and timeout settings.
120
+ const propsRef = useValueAsRef({
121
+ timeout,
122
+ addEndListener,
123
+ reduceMotion,
124
+ getAutoTimeout,
125
+ onEnter,
126
+ onEntering,
127
+ onEntered,
128
+ onExit,
129
+ onExiting,
130
+ onExited,
131
+ enter,
132
+ exit,
133
+ mountOnEnter,
134
+ unmountOnExit,
135
+ nodeRef,
136
+ parentGroup
137
+ });
138
+
139
+ // Effects below depend on these helpers. Keep their identity stable; they read
140
+ // changing props through propsRef.
141
+ const cancelPendingCallback = React.useCallback(() => {
142
+ if (nextCallbackRef.current !== null) {
143
+ nextCallbackRef.current.cancel();
144
+ nextCallbackRef.current = null;
145
+ }
146
+ }, []);
147
+ const makeCallback = React.useCallback(handler => {
148
+ let active = true;
149
+ const wrapped = () => {
150
+ if (active) {
151
+ active = false;
152
+ nextCallbackRef.current = null;
153
+ handler();
154
+ }
155
+ };
156
+ wrapped.cancel = () => {
157
+ active = false;
158
+ };
159
+ nextCallbackRef.current = wrapped;
160
+ return wrapped;
161
+ }, []);
162
+ const scheduleTransitionEnd = React.useCallback((nextStatus, currentStatus) => {
163
+ let timeoutId;
164
+ const clearTimer = () => {
165
+ if (timeoutId !== undefined) {
166
+ clearTimeout(timeoutId);
167
+ timeoutId = undefined;
168
+ }
169
+ };
170
+ const done = makeCallback(() => {
171
+ clearTimer();
172
+ statusRef.current = nextStatus;
173
+ setStatus(nextStatus);
174
+ });
175
+ const cancelDone = done.cancel;
176
+ done.cancel = () => {
177
+ clearTimer();
178
+ cancelDone();
179
+ };
180
+ const node = propsRef.current.nodeRef.current;
181
+ const listener = propsRef.current.addEndListener;
182
+ const hasAutoTimeout = propsRef.current.getAutoTimeout !== undefined;
183
+ const autoTimeout = propsRef.current.getAutoTimeout?.();
184
+ const authoredTimeout = getCompletionTimeout({
185
+ currentStatus,
186
+ isAppearing: isAppearingRef.current,
187
+ timeout: propsRef.current.timeout,
188
+ autoTimeout
189
+ });
190
+ const transitionReduceMotion = transitionReduceMotionRef.current;
191
+ // Auto-duration consumers may skip measurement under reduced motion, but
192
+ // still need a 0ms timeout when they provide addEndListener.
193
+ const fallbackTimeout = authoredTimeout ?? (transitionReduceMotion && hasAutoTimeout ? 0 : null);
194
+ const scheduleTimer = value => {
195
+ timeoutId = setTimeout(done, value);
196
+ };
197
+ if (!node) {
198
+ if (process.env.NODE_ENV !== 'production') {
199
+ 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'));
200
+ }
201
+
202
+ // Match react-transition-group: if there is no DOM node, there is no
203
+ // transition to observe, so finish on the next tick.
204
+ scheduleTimer(0);
205
+ return;
206
+ }
207
+ if (listener) {
208
+ if (fallbackTimeout != null) {
209
+ scheduleTimer(transitionReduceMotion ? 0 : fallbackTimeout);
210
+ }
211
+
212
+ // With nodeRef, react-transition-group calls addEndListener(done).
213
+ // Material UI has long supported addEndListener(node, done). Keep both call
214
+ // shapes so existing transition wrappers do not have to change.
215
+ if (listener.length >= 2) {
216
+ listener(node, done);
217
+ } else {
218
+ listener(done);
219
+ }
220
+ return;
221
+ }
222
+ scheduleTimer(transitionReduceMotion ? 0 : authoredTimeout ?? 0);
223
+ }, [makeCallback, propsRef]);
224
+ const performEnter = React.useCallback(mounting => {
225
+ const current = propsRef.current;
226
+ const isAppearing = current.parentGroup ? current.parentGroup.isMounting : mounting;
227
+ isAppearingRef.current = isAppearing;
228
+
229
+ // On updates, enter=false skips the enter animation. Move straight to
230
+ // entered; the status effect will call onEntered, but onEnter/onEntering
231
+ // must not fire.
232
+ if (!mounting && !current.enter) {
233
+ statusRef.current = 'entered';
234
+ setStatus('entered');
235
+ return;
236
+ }
237
+ transitionReduceMotionRef.current = current.reduceMotion;
238
+ current.onEnter?.(isAppearing);
239
+ statusRef.current = 'entering';
240
+ setStatus('entering');
241
+ }, [propsRef]);
242
+ const performExit = React.useCallback(() => {
243
+ const current = propsRef.current;
244
+ if (!current.exit) {
245
+ statusRef.current = 'exited';
246
+ setStatus('exited');
247
+ return;
248
+ }
249
+ transitionReduceMotionRef.current = current.reduceMotion;
250
+ current.onExit?.();
251
+ statusRef.current = 'exiting';
252
+ setStatus('exiting');
253
+ }, [propsRef]);
254
+ const updateStatus = React.useCallback((mounting, nextStatus) => {
255
+ cancelPendingCallback();
256
+ if (nextStatus === 'entering') {
257
+ const current = propsRef.current;
258
+ // If the node was just mounted, read layout before entering so the
259
+ // browser applies the starting styles before the animation begins.
260
+ if (current.mountOnEnter || current.unmountOnExit) {
261
+ const node = current.nodeRef.current;
262
+ if (node) {
263
+ reflow(node);
264
+ }
265
+ }
266
+ performEnter(mounting);
267
+ } else {
268
+ performExit();
269
+ }
270
+ }, [cancelPendingCallback, performEnter, performExit, propsRef]);
271
+
272
+ // Runs on mount. useEnhancedEffect is needed because the initial appear
273
+ // transition may read layout before paint. In StrictMode development builds,
274
+ // React mounts, cleans up, and mounts again; cleanup cancels pending work and
275
+ // the second mount restarts the same transition.
276
+ useEnhancedEffect(() => {
277
+ mountedRef.current = true;
278
+ if (shouldAppearOnMountRef.current) {
279
+ shouldAppearOnMountRef.current = false;
280
+ updateStatus(true, 'entering');
281
+ }
282
+ return () => {
283
+ mountedRef.current = false;
284
+ cancelPendingCallback();
285
+ };
286
+ }, [cancelPendingCallback, updateStatus]);
287
+
288
+ // Reconcile the rendered status after `in` or status changes:
289
+ // - opening from unmounted is handled during render (see above) so the child
290
+ // is committed as exited with its ref attached before this effect runs.
291
+ // - unmountOnExit removes the child after the exited state commits.
292
+ // This matches react-transition-group's observable status steps without
293
+ // running work after unrelated commits.
294
+ useEnhancedEffect(() => {
295
+ if (!mountedRef.current) {
296
+ return;
297
+ }
298
+ const current = statusRef.current;
299
+ if (inProp) {
300
+ if (current !== 'entering' && current !== 'entered') {
301
+ updateStatus(false, 'entering');
302
+ }
303
+ } else if (current === 'entering' || current === 'entered') {
304
+ updateStatus(false, 'exiting');
305
+ } else if (current === 'exited' && unmountOnExit) {
306
+ statusRef.current = 'unmounted';
307
+ setStatus('unmounted');
308
+ }
309
+ }, [inProp, status, unmountOnExit, updateStatus]);
310
+
311
+ // Fire lifecycle callbacks for committed status changes. The guard prevents
312
+ // duplicate callbacks in StrictMode; propsRef keeps delayed callbacks fresh.
313
+ useEnhancedEffect(() => {
314
+ // `unmounted` is bookkeeping, not a real transition state. Do not fire
315
+ // callbacks when moving into or out of it; otherwise the first open with
316
+ // mountOnEnter/unmountOnExit would look like a completed exit.
317
+ if (status === 'unmounted' || lastFiredStatusRef.current === 'unmounted') {
318
+ lastFiredStatusRef.current = status;
319
+ return;
320
+ }
321
+ const prev = lastFiredStatusRef.current;
322
+ if (prev === status) {
323
+ return;
324
+ }
325
+ lastFiredStatusRef.current = status;
326
+ const current = propsRef.current;
327
+ if (status === 'entering') {
328
+ current.onEntering?.(isAppearingRef.current);
329
+ scheduleTransitionEnd('entered', 'entering');
330
+ } else if (status === 'exiting') {
331
+ current.onExiting?.();
332
+ scheduleTransitionEnd('exited', 'exiting');
333
+ } else if (status === 'entered') {
334
+ current.onEntered?.(isAppearingRef.current);
335
+ } else if (status === 'exited') {
336
+ current.onExited?.();
337
+ }
338
+ }, [propsRef, scheduleTransitionEnd, status]);
339
+ if (status === 'unmounted') {
340
+ return null;
341
+ }
342
+
343
+ // Nested Material UI transitions should not inherit this transition's parent group.
344
+ // A null context keeps an outer TransitionGroup from controlling them.
345
+ return /*#__PURE__*/_jsx(TransitionGroupContext.Provider, {
346
+ value: null,
347
+ children: children(status, childProps)
348
+ });
349
+ }
350
+ process.env.NODE_ENV !== "production" ? Transition.propTypes /* remove-proptypes */ = {
351
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
352
+ // │ These PropTypes are generated from the TypeScript type definitions. │
353
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
354
+ // └─────────────────────────────────────────────────────────────────────┘
355
+ /**
356
+ * @ignore
357
+ */
358
+ addEndListener: PropTypes.func,
359
+ /**
360
+ * @ignore
361
+ */
362
+ appear: PropTypes.bool,
363
+ /**
364
+ * @ignore
365
+ */
366
+ children: PropTypes.func.isRequired,
367
+ /**
368
+ * @ignore
369
+ */
370
+ enter: PropTypes.bool,
371
+ /**
372
+ * @ignore
373
+ */
374
+ exit: PropTypes.bool,
375
+ /**
376
+ * @ignore
377
+ */
378
+ getAutoTimeout: PropTypes.func,
379
+ /**
380
+ * @ignore
381
+ */
382
+ in: PropTypes.bool,
383
+ /**
384
+ * @ignore
385
+ */
386
+ mountOnEnter: PropTypes.bool,
387
+ /**
388
+ * @ignore
389
+ */
390
+ nodeRef: PropTypes.shape({
391
+ current: (props, propName) => {
392
+ if (props[propName] == null) {
393
+ return null;
394
+ }
395
+ if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) {
396
+ return new Error(`Expected prop '${propName}' to be of type Element`);
397
+ }
398
+ return null;
399
+ }
400
+ }).isRequired,
401
+ /**
402
+ * @ignore
403
+ */
404
+ onEnter: PropTypes.func,
405
+ /**
406
+ * @ignore
407
+ */
408
+ onEntered: PropTypes.func,
409
+ /**
410
+ * @ignore
411
+ */
412
+ onEntering: PropTypes.func,
413
+ /**
414
+ * @ignore
415
+ */
416
+ onExit: PropTypes.func,
417
+ /**
418
+ * @ignore
419
+ */
420
+ onExited: PropTypes.func,
421
+ /**
422
+ * @ignore
423
+ */
424
+ onExiting: PropTypes.func,
425
+ /**
426
+ * @ignore
427
+ */
428
+ reduceMotion: PropTypes.bool,
429
+ /**
430
+ * @ignore
431
+ */
432
+ timeout: PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
433
+ appear: PropTypes.number,
434
+ enter: PropTypes.number,
435
+ exit: PropTypes.number
436
+ })]),
437
+ /**
438
+ * @ignore
439
+ */
440
+ unmountOnExit: PropTypes.bool
441
+ } : void 0;
442
+ 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.1",
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",
38
- "@mui/types": "^9.0.0",
39
- "@mui/utils": "^9.0.1"
36
+ "@mui/core-downloads-tracker": "^9.1.1",
37
+ "@mui/system": "^9.1.1",
38
+ "@mui/types": "^9.1.1",
39
+ "@mui/utils": "^9.1.1"
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.1"
48
48
  },
49
49
  "peerDependenciesMeta": {
50
50
  "@types/react": {
@@ -27,19 +27,19 @@ declare const getInitColorSchemeScript: typeof deprecatedGetInitColorSchemeScrip
27
27
  */
28
28
  export declare const CssVarsProvider: (props: import("react").PropsWithChildren<Partial<import("@mui/system").CssVarsProviderConfig<SupportedColorScheme>> & {
29
29
  theme?: {
30
- cssVariables?: false | undefined;
31
- cssVarPrefix?: string | undefined;
32
- colorSchemes: Partial<Record<SupportedColorScheme, any>>;
33
- colorSchemeSelector?: "media" | "class" | "data" | string | undefined;
34
- } | {
35
30
  $$material: {
36
31
  cssVariables?: false | undefined;
37
32
  cssVarPrefix?: string | undefined;
38
33
  colorSchemes: Partial<Record<SupportedColorScheme, any>>;
39
- colorSchemeSelector?: "media" | "class" | "data" | string | undefined;
34
+ colorSchemeSelector?: 'media' | 'class' | 'data' | string | undefined;
40
35
  };
36
+ } | {
37
+ cssVariables?: false | undefined;
38
+ cssVarPrefix?: string | undefined;
39
+ colorSchemes: Partial<Record<SupportedColorScheme, any>>;
40
+ colorSchemeSelector?: 'media' | 'class' | 'data' | string | undefined;
41
41
  } | undefined;
42
- defaultMode?: "light" | "dark" | "system" | undefined;
42
+ defaultMode?: 'light' | 'dark' | 'system' | undefined;
43
43
  documentNode?: Document | null | undefined;
44
44
  colorSchemeNode?: Element | null | undefined;
45
45
  storageManager?: import("@mui/system").StorageManager | null | undefined;
@@ -27,19 +27,19 @@ declare const getInitColorSchemeScript: typeof deprecatedGetInitColorSchemeScrip
27
27
  */
28
28
  export declare const CssVarsProvider: (props: import("react").PropsWithChildren<Partial<import("@mui/system").CssVarsProviderConfig<SupportedColorScheme>> & {
29
29
  theme?: {
30
- cssVariables?: false | undefined;
31
- cssVarPrefix?: string | undefined;
32
- colorSchemes: Partial<Record<SupportedColorScheme, any>>;
33
- colorSchemeSelector?: "media" | "class" | "data" | string | undefined;
34
- } | {
35
30
  $$material: {
36
31
  cssVariables?: false | undefined;
37
32
  cssVarPrefix?: string | undefined;
38
33
  colorSchemes: Partial<Record<SupportedColorScheme, any>>;
39
- colorSchemeSelector?: "media" | "class" | "data" | string | undefined;
34
+ colorSchemeSelector?: 'media' | 'class' | 'data' | string | undefined;
40
35
  };
36
+ } | {
37
+ cssVariables?: false | undefined;
38
+ cssVarPrefix?: string | undefined;
39
+ colorSchemes: Partial<Record<SupportedColorScheme, any>>;
40
+ colorSchemeSelector?: 'media' | 'class' | 'data' | string | undefined;
41
41
  } | undefined;
42
- defaultMode?: "light" | "dark" | "system" | undefined;
42
+ defaultMode?: 'light' | 'dark' | 'system' | undefined;
43
43
  documentNode?: Document | null | undefined;
44
44
  colorSchemeNode?: Element | null | undefined;
45
45
  storageManager?: import("@mui/system").StorageManager | null | undefined;
@@ -1,10 +1,10 @@
1
1
  declare const _default: <T extends {
2
2
  rootSelector?: string | undefined;
3
- colorSchemeSelector?: "media" | "class" | "data" | string | undefined;
3
+ colorSchemeSelector?: 'media' | 'class' | 'data' | string | undefined;
4
4
  colorSchemes?: Record<string, any> | undefined;
5
5
  defaultColorScheme?: string | undefined;
6
6
  cssVarPrefix?: string | undefined;
7
- }>(theme: T) => (colorScheme: keyof T["colorSchemes"] | undefined, css: Record<string, any>) => string | {
7
+ }>(theme: T) => (colorScheme: keyof T['colorSchemes'] | undefined, css: Record<string, any>) => string | {
8
8
  [x: string]: Record<string, any>;
9
9
  "@media (prefers-color-scheme: dark)": {
10
10
  [x: string]: Record<string, any>;
@@ -1,10 +1,10 @@
1
1
  declare const _default: <T extends {
2
2
  rootSelector?: string | undefined;
3
- colorSchemeSelector?: "media" | "class" | "data" | string | undefined;
3
+ colorSchemeSelector?: 'media' | 'class' | 'data' | string | undefined;
4
4
  colorSchemes?: Record<string, any> | undefined;
5
5
  defaultColorScheme?: string | undefined;
6
6
  cssVarPrefix?: string | undefined;
7
- }>(theme: T) => (colorScheme: keyof T["colorSchemes"] | undefined, css: Record<string, any>) => string | {
7
+ }>(theme: T) => (colorScheme: keyof T['colorSchemes'] | undefined, css: Record<string, any>) => string | {
8
8
  [x: string]: Record<string, any>;
9
9
  "@media (prefers-color-scheme: dark)": {
10
10
  [x: string]: Record<string, any>;
@@ -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 : {});