Skip to content

Commit 25096df

Browse files
mbrookesoliviertassinari
authored andcommitted
[Menu] Deprecate transition onX props (#22213)
1 parent a3df136 commit 25096df

File tree

4 files changed

+149
-16
lines changed

4 files changed

+149
-16
lines changed

docs/pages/api-docs/menu.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,16 @@ The `MuiMenu` name can be used for providing [default props](/customization/glob
3535
| <span class="prop-name">disableAutoFocusItem</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | When opening the menu will not focus the active item but the `[role="menu"]` unless `autoFocus` is also set to `false`. Not using the default means not following WAI-ARIA authoring practices. Please be considerate about possible accessibility implications. |
3636
| <span class="prop-name">MenuListProps</span> | <span class="prop-type">object</span> | <span class="prop-default">{}</span> | Props applied to the [`MenuList`](/api/menu-list/) element. |
3737
| <span class="prop-name">onClose</span> | <span class="prop-type">func</span> | | Callback fired when the component requests to be closed.<br><br>**Signature:**<br>`function(event: object, reason: string) => void`<br>*event:* The event source of the callback.<br>*reason:* Can be: `"escapeKeyDown"`, `"backdropClick"`, `"tabKeyDown"`. |
38-
| <span class="prop-name">onEnter</span> | <span class="prop-type">func</span> | | Callback fired before the Menu enters. |
39-
| <span class="prop-name">onEntered</span> | <span class="prop-type">func</span> | | Callback fired when the Menu has entered. |
40-
| <span class="prop-name">onEntering</span> | <span class="prop-type">func</span> | | Callback fired when the Menu is entering. |
41-
| <span class="prop-name">onExit</span> | <span class="prop-type">func</span> | | Callback fired before the Menu exits. |
42-
| <span class="prop-name">onExited</span> | <span class="prop-type">func</span> | | Callback fired when the Menu has exited. |
43-
| <span class="prop-name">onExiting</span> | <span class="prop-type">func</span> | | Callback fired when the Menu is exiting. |
38+
| ~~<span class="prop-name">onEnter</span>~~ | <span class="prop-type">func</span> | | *Deprecated*. Use the `TransitionProps` prop instead.<br><br>Callback fired before the Menu enters. |
39+
| ~~<span class="prop-name">onEntered</span>~~ | <span class="prop-type">func</span> | | *Deprecated*. Use the `TransitionProps` prop instead.<br><br>Callback fired when the Menu has entered. |
40+
| ~~<span class="prop-name">onEntering</span>~~ | <span class="prop-type">func</span> | | *Deprecated*. Use the `TransitionProps` prop instead.<br><br>Callback fired when the Menu is entering. |
41+
| ~~<span class="prop-name">onExit</span>~~ | <span class="prop-type">func</span> | | *Deprecated*. Use the `TransitionProps` prop instead.<br><br>Callback fired before the Menu exits. |
42+
| ~~<span class="prop-name">onExited</span>~~ | <span class="prop-type">func</span> | | *Deprecated*. Use the `TransitionProps` prop instead.<br><br>Callback fired when the Menu has exited. |
43+
| ~~<span class="prop-name">onExiting</span>~~ | <span class="prop-type">func</span> | | *Deprecated*. Use the `TransitionProps` prop instead.<br><br>Callback fired when the Menu is exiting. |
4444
| <span class="prop-name required">open<abbr title="required">*</abbr></span> | <span class="prop-type">bool</span> | | If `true`, the menu is visible. |
4545
| <span class="prop-name">PopoverClasses</span> | <span class="prop-type">object</span> | | `classes` prop applied to the [`Popover`](/api/popover/) element. |
4646
| <span class="prop-name">transitionDuration</span> | <span class="prop-type">'auto'<br>&#124;&nbsp;number<br>&#124;&nbsp;{ appear?: number, enter?: number, exit?: number }</span> | <span class="prop-default">'auto'</span> | The length of the transition in `ms`, or 'auto' |
47+
| <span class="prop-name">TransitionProps</span> | <span class="prop-type">object</span> | <span class="prop-default">{}</span> | Props applied to the transition element. By default, the element is based on this [`Transition`](http://reactcommunity.org/react-transition-group/transition) component. |
4748
| <span class="prop-name">variant</span> | <span class="prop-type">'menu'<br>&#124;&nbsp;'selectedMenu'</span> | <span class="prop-default">'selectedMenu'</span> | The variant to use. Use `menu` to prevent selected items from impacting the initial focus and the vertical alignment relative to the anchor element. |
4849

4950
The `ref` is forwarded to the root element.

packages/material-ui/src/Menu/Menu.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ export interface MenuProps
8484
* The length of the transition in `ms`, or 'auto'
8585
*/
8686
transitionDuration?: TransitionProps['timeout'] | 'auto';
87+
/**
88+
* Props applied to the transition element.
89+
* By default, the element is based on this [`Transition`](http://reactcommunity.org/react-transition-group/transition) component.
90+
*/
91+
TransitionProps?: TransitionProps;
8792
/**
8893
* The variant to use. Use `menu` to prevent selected items from impacting the initial focus
8994
* and the vertical alignment relative to the anchor element.

packages/material-ui/src/Menu/Menu.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import MenuList from '../MenuList';
99
import * as ReactDOM from 'react-dom';
1010
import setRef from '../utils/setRef';
1111
import useTheme from '../styles/useTheme';
12+
import deprecatedPropType from '../utils/deprecatedPropType';
1213

1314
const RTL_ORIGIN = {
1415
vertical: 'top',
@@ -45,11 +46,12 @@ const Menu = React.forwardRef(function Menu(props, ref) {
4546
disableAutoFocusItem = false,
4647
MenuListProps = {},
4748
onClose,
48-
onEntering,
49+
onEntering: onEnteringProp,
4950
open,
5051
PaperProps = {},
5152
PopoverClasses,
5253
transitionDuration = 'auto',
54+
TransitionProps: { onEntering, ...TransitionProps } = {},
5355
variant = 'selectedMenu',
5456
...other
5557
} = props;
@@ -66,7 +68,9 @@ const Menu = React.forwardRef(function Menu(props, ref) {
6668
if (menuListActionsRef.current) {
6769
menuListActionsRef.current.adjustStyleForScrollbar(element, theme);
6870
}
69-
71+
if (onEnteringProp) {
72+
onEnteringProp(element, isAppearing);
73+
}
7074
if (onEntering) {
7175
onEntering(element, isAppearing);
7276
}
@@ -135,7 +139,7 @@ const Menu = React.forwardRef(function Menu(props, ref) {
135139
getContentAnchorEl={getContentAnchorEl}
136140
classes={PopoverClasses}
137141
onClose={onClose}
138-
TransitionProps={{ onEntering: handleEntering }}
142+
TransitionProps={{ onEntering: handleEntering, ...TransitionProps }}
139143
anchorOrigin={theme.direction === 'rtl' ? RTL_ORIGIN : LTR_ORIGIN}
140144
transformOrigin={theme.direction === 'rtl' ? RTL_ORIGIN : LTR_ORIGIN}
141145
PaperProps={{
@@ -216,27 +220,27 @@ Menu.propTypes = {
216220
/**
217221
* Callback fired before the Menu enters.
218222
*/
219-
onEnter: PropTypes.func,
223+
onEnter: deprecatedPropType(PropTypes.func, 'Use the `TransitionProps` prop instead.'),
220224
/**
221225
* Callback fired when the Menu has entered.
222226
*/
223-
onEntered: PropTypes.func,
227+
onEntered: deprecatedPropType(PropTypes.func, 'Use the `TransitionProps` prop instead.'),
224228
/**
225229
* Callback fired when the Menu is entering.
226230
*/
227-
onEntering: PropTypes.func,
231+
onEntering: deprecatedPropType(PropTypes.func, 'Use the `TransitionProps` prop instead.'),
228232
/**
229233
* Callback fired before the Menu exits.
230234
*/
231-
onExit: PropTypes.func,
235+
onExit: deprecatedPropType(PropTypes.func, 'Use the `TransitionProps` prop instead.'),
232236
/**
233237
* Callback fired when the Menu has exited.
234238
*/
235-
onExited: PropTypes.func,
239+
onExited: deprecatedPropType(PropTypes.func, 'Use the `TransitionProps` prop instead.'),
236240
/**
237241
* Callback fired when the Menu is exiting.
238242
*/
239-
onExiting: PropTypes.func,
243+
onExiting: deprecatedPropType(PropTypes.func, 'Use the `TransitionProps` prop instead.'),
240244
/**
241245
* If `true`, the menu is visible.
242246
*/
@@ -261,6 +265,11 @@ Menu.propTypes = {
261265
exit: PropTypes.number,
262266
}),
263267
]),
268+
/**
269+
* Props applied to the transition element.
270+
* By default, the element is based on this [`Transition`](http://reactcommunity.org/react-transition-group/transition) component.
271+
*/
272+
TransitionProps: PropTypes.object,
264273
/**
265274
* The variant to use. Use `menu` to prevent selected items from impacting the initial focus
266275
* and the vertical alignment relative to the anchor element.

packages/material-ui/src/Menu/Menu.test.js

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as React from 'react';
2-
import { spy } from 'sinon';
2+
import * as PropTypes from 'prop-types';
3+
import { spy, stub } from 'sinon';
34
import { expect } from 'chai';
45
import { getClasses } from '@material-ui/core/test-utils';
56
import createMount from 'test/utils/createMount';
@@ -37,6 +38,15 @@ describe('<Menu />', () => {
3738
}));
3839

3940
describe('event callbacks', () => {
41+
beforeEach(() => {
42+
PropTypes.resetWarningCache();
43+
stub(console, 'error');
44+
});
45+
46+
afterEach(() => {
47+
console.error.restore();
48+
});
49+
4050
describe('entering', () => {
4151
it('should fire callbacks', (done) => {
4252
const handleEnter = spy();
@@ -93,6 +103,114 @@ describe('<Menu />', () => {
93103
});
94104
});
95105
});
106+
107+
describe('prop: onEnter', () => {
108+
it('issues a warning', () => {
109+
PropTypes.checkPropTypes(
110+
Menu.Naked.propTypes,
111+
{
112+
onEnter: () => [],
113+
},
114+
'prop',
115+
'Menu',
116+
);
117+
118+
expect(console.error.callCount).to.equal(2);
119+
expect(console.error.firstCall.args[0]).to.equal(
120+
'Warning: Failed prop type: The prop `onEnter` of `Menu` is deprecated. Use the `TransitionProps` prop instead.',
121+
);
122+
});
123+
});
124+
125+
describe('prop: onEntering', () => {
126+
it('issues a warning', () => {
127+
PropTypes.checkPropTypes(
128+
Menu.Naked.propTypes,
129+
{
130+
onEntering: () => [],
131+
},
132+
'prop',
133+
'Menu',
134+
);
135+
136+
expect(console.error.callCount).to.equal(2);
137+
expect(console.error.firstCall.args[0]).to.equal(
138+
'Warning: Failed prop type: The prop `onEntering` of `Menu` is deprecated. Use the `TransitionProps` prop instead.',
139+
);
140+
});
141+
});
142+
143+
describe('prop: onEntered', () => {
144+
it('issues a warning', () => {
145+
PropTypes.checkPropTypes(
146+
Menu.Naked.propTypes,
147+
{
148+
onEntered: () => [],
149+
},
150+
'prop',
151+
'Menu',
152+
);
153+
154+
expect(console.error.callCount).to.equal(2);
155+
expect(console.error.firstCall.args[0]).to.equal(
156+
'Warning: Failed prop type: The prop `onEntered` of `Menu` is deprecated. Use the `TransitionProps` prop instead.',
157+
);
158+
});
159+
});
160+
161+
describe('prop: onExit', () => {
162+
it('issues a warning', () => {
163+
PropTypes.checkPropTypes(
164+
Menu.Naked.propTypes,
165+
{
166+
onExit: () => [],
167+
},
168+
'prop',
169+
'Menu',
170+
);
171+
172+
expect(console.error.callCount).to.equal(2);
173+
expect(console.error.firstCall.args[0]).to.equal(
174+
'Warning: Failed prop type: The prop `onExit` of `Menu` is deprecated. Use the `TransitionProps` prop instead.',
175+
);
176+
});
177+
});
178+
179+
describe('prop: onExiting', () => {
180+
it('issues a warning', () => {
181+
PropTypes.checkPropTypes(
182+
Menu.Naked.propTypes,
183+
{
184+
onExiting: () => [],
185+
},
186+
'prop',
187+
'Menu',
188+
);
189+
190+
expect(console.error.callCount).to.equal(2);
191+
expect(console.error.firstCall.args[0]).to.equal(
192+
'Warning: Failed prop type: The prop `onExiting` of `Menu` is deprecated. Use the `TransitionProps` prop instead.',
193+
);
194+
});
195+
});
196+
197+
describe('prop: onExited', () => {
198+
it('issues a warning', () => {
199+
PropTypes.checkPropTypes(
200+
Menu.Naked.propTypes,
201+
{
202+
onExited: () => [],
203+
},
204+
'prop',
205+
'Menu',
206+
);
207+
208+
expect(console.error.callCount).to.equal(2);
209+
expect(console.error.firstCall.args[0]).to.equal(
210+
'Warning: Failed prop type: The prop `onExited` of `Menu` is deprecated. Use the `TransitionProps` prop instead.',
211+
);
212+
});
213+
});
96214
});
97215

98216
it('should pass `classes.paper` to the Popover', () => {

0 commit comments

Comments
 (0)