diff --git a/docs/data/material/migration/upgrade-to-v9/upgrade-to-v9.md b/docs/data/material/migration/upgrade-to-v9/upgrade-to-v9.md index 1742e1e49a5f42..1bcc2b03d87bba 100644 --- a/docs/data/material/migration/upgrade-to-v9/upgrade-to-v9.md +++ b/docs/data/material/migration/upgrade-to-v9/upgrade-to-v9.md @@ -500,6 +500,42 @@ If you render a `TextField` from `Autocomplete`, the `params` shape also changed )} ``` +#### Tooltip deprecated props removed + +Use the [tooltip-props codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#tooltip-props) below to migrate the code as described in the following section: + +```bash +npx @mui/codemod@latest deprecations/tooltip-props +``` + +The following deprecated props have been removed from the `Tooltip` component: + +- `components` → use `slots` +- `componentsProps` → use `slotProps` +- `PopperComponent` → use `slots.popper` +- `PopperProps` → use `slotProps.popper` +- `TransitionComponent` → use `slots.transition` +- `TransitionProps` → use `slotProps.transition` + +```diff + +``` + #### Alert deprecated props removed Use the [alert-props codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#alert-props) below to migrate the code as described in the following section: diff --git a/docs/pages/material-ui/api/tooltip.json b/docs/pages/material-ui/api/tooltip.json index 052b2f230d2fd7..574a1dedc6b077 100644 --- a/docs/pages/material-ui/api/tooltip.json +++ b/docs/pages/material-ui/api/tooltip.json @@ -3,24 +3,6 @@ "children": { "type": { "name": "custom", "description": "element" }, "required": true }, "arrow": { "type": { "name": "bool" }, "default": "false" }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "components": { - "type": { - "name": "shape", - "description": "{ Arrow?: elementType, Popper?: elementType, Tooltip?: elementType, Transition?: elementType }" - }, - "default": "{}", - "deprecated": true, - "deprecationInfo": "use the slots prop instead. This prop will be removed in a future major release. See Migrating from deprecated APIs for more details." - }, - "componentsProps": { - "type": { - "name": "shape", - "description": "{ arrow?: object, popper?: object, tooltip?: object, transition?: object }" - }, - "default": "{}", - "deprecated": true, - "deprecationInfo": "use the slotProps prop instead. This prop will be removed in a future major release. See Migrating from deprecated APIs for more details." - }, "describeChild": { "type": { "name": "bool" }, "default": "false" }, "disableFocusListener": { "type": { "name": "bool" }, "default": "false" }, "disableHoverListener": { "type": { "name": "bool" }, "default": "false" }, @@ -55,17 +37,6 @@ }, "default": "'bottom'" }, - "PopperComponent": { - "type": { "name": "elementType" }, - "deprecated": true, - "deprecationInfo": "use the slots.popper prop instead. This prop will be removed in a future major release. See Migrating from deprecated APIs for more details." - }, - "PopperProps": { - "type": { "name": "object" }, - "default": "{}", - "deprecated": true, - "deprecationInfo": "use the slotProps.popper prop instead. This prop will be removed in a future major release. See Migrating from deprecated APIs for more details." - }, "slotProps": { "type": { "name": "shape", @@ -87,18 +58,7 @@ }, "additionalInfo": { "sx": true } }, - "title": { "type": { "name": "node" } }, - "TransitionComponent": { - "type": { "name": "elementType" }, - "deprecated": true, - "deprecationInfo": "use the slots.transition prop instead. This prop will be removed in a future major release. See Migrating from deprecated APIs for more details." - }, - "TransitionProps": { - "type": { "name": "object" }, - "default": "{}", - "deprecated": true, - "deprecationInfo": "use the slotProps.transition prop instead. This prop will be removed in a future major release. See Migrating from deprecated APIs for more details." - } + "title": { "type": { "name": "node" } } }, "name": "Tooltip", "imports": [ diff --git a/docs/src/components/about/Team.tsx b/docs/src/components/about/Team.tsx index 80e8d02fda8660..4b60ab11935153 100644 --- a/docs/src/components/about/Team.tsx +++ b/docs/src/components/about/Team.tsx @@ -67,16 +67,18 @@ function Person(props: Profile & { sx?: PaperProps['sx'] }) { title={props.location || false} placement="right-end" describeChild - PopperProps={{ - popperOptions: { - modifiers: [ - { - name: 'offset', - options: { - offset: [3, 2], + slotProps={{ + popper: { + popperOptions: { + modifiers: [ + { + name: 'offset', + options: { + offset: [3, 2], + }, }, - }, - ], + ], + }, }, }} > diff --git a/docs/translations/api-docs/tooltip/tooltip.json b/docs/translations/api-docs/tooltip/tooltip.json index 9f006581b9ff92..75d36c7963bb8f 100644 --- a/docs/translations/api-docs/tooltip/tooltip.json +++ b/docs/translations/api-docs/tooltip/tooltip.json @@ -4,10 +4,6 @@ "arrow": { "description": "If true, adds an arrow to the tooltip." }, "children": { "description": "Tooltip reference element.", "requiresRef": true }, "classes": { "description": "Override or extend the styles applied to the component." }, - "components": { "description": "The components used for each slot inside." }, - "componentsProps": { - "description": "The extra props for the slot components. You can override the existing props or add new ones." - }, "describeChild": { "description": "Set to true if the title acts as an accessible description. By default the title acts as an accessible label for the child." }, @@ -52,10 +48,6 @@ }, "open": { "description": "If true, the component is shown." }, "placement": { "description": "Tooltip placement." }, - "PopperComponent": { "description": "The component used for the popper." }, - "PopperProps": { - "description": "Props applied to the Popper element." - }, "slotProps": { "description": "The props used for each slot inside." }, "slots": { "description": "The components used for each slot inside." }, "sx": { @@ -63,12 +55,6 @@ }, "title": { "description": "Tooltip title. Zero-length titles string, undefined, null and false are never displayed." - }, - "TransitionComponent": { - "description": "The component used for the transition. Follow this guide to learn more about the requirements for this component." - }, - "TransitionProps": { - "description": "Props applied to the transition element. By default, the element is based on this Transition component." } }, "classDescriptions": { diff --git a/packages/mui-codemod/README.md b/packages/mui-codemod/README.md index 1f2892206c6435..f1f5512c6b8a01 100644 --- a/packages/mui-codemod/README.md +++ b/packages/mui-codemod/README.md @@ -1954,19 +1954,21 @@ npx @mui/codemod@next deprecations/slider-classes ```diff - TransitionComponent: CustomTransitionComponent, - PopperProps: CustomPopperProps, - TransitionProps: CustomTransitionProps, -- components: { Arrow: CustomArrow } +- components: { Arrow: CustomArrow, Tooltip: CustomTooltip } + slots: { + arrow: CustomArrow, ++ tooltip: CustomTooltip, + popper: CustomPopperComponent, + transition: CustomTransitionComponent, + }, -- componentsProps: { arrow: { testid: 'test-id' }} +- componentsProps: { arrow: { testid: 'test-id' }, tooltip: { className: 'custom' } } + slotProps: { + arrow: { testid: 'test-id' }, ++ tooltip: { className: 'custom' }, + popper: CustomPopperProps, + transition: CustomTransitionProps, + }, diff --git a/packages/mui-material/src/Popper/Popper.spec.tsx b/packages/mui-material/src/Popper/Popper.spec.tsx index ef4d76146d3616..407ec46ac55439 100644 --- a/packages/mui-material/src/Popper/Popper.spec.tsx +++ b/packages/mui-material/src/Popper/Popper.spec.tsx @@ -19,8 +19,8 @@ export default function ValueLabelComponent(props: Props) { return ( | undefined; - /** - * The components used for each slot inside. - * - * @deprecated use the `slots` prop instead. This prop will be removed in a future major release. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details. - * - * @default {} - */ - components?: - | { - Popper?: React.ElementType | undefined; - Transition?: React.ElementType | undefined; - Tooltip?: React.ElementType | undefined; - Arrow?: React.ElementType | undefined; - } - | undefined; - /** - * The extra props for the slot components. - * You can override the existing props or add new ones. - * - * @deprecated use the `slotProps` prop instead. This prop will be removed in a future major release. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details. - * - * @default {} - */ - componentsProps?: - | { - popper?: (Partial & TooltipComponentsPropsOverrides) | undefined; - transition?: (TransitionProps & TooltipComponentsPropsOverrides) | undefined; - tooltip?: - | (React.HTMLProps & - MUIStyledCommonProps & - TooltipComponentsPropsOverrides) - | undefined; - arrow?: - | (React.HTMLProps & - MUIStyledCommonProps & - TooltipComponentsPropsOverrides) - | undefined; - } - | undefined; /** * Set to `true` if the `title` acts as an accessible description. * By default the `title` acts as an accessible label for the child. @@ -212,17 +171,6 @@ export interface TooltipProps * @default 'bottom' */ placement?: PopperProps['placement'] | undefined; - /** - * The component used for the popper. - * @deprecated use the `slots.popper` prop instead. This prop will be removed in a future major release. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details. - */ - PopperComponent?: React.JSXElementConstructor | undefined; - /** - * Props applied to the [`Popper`](https://mui.com/material-ui/api/popper/) element. - * @deprecated use the `slotProps.popper` prop instead. This prop will be removed in a future major release. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details. - * @default {} - */ - PopperProps?: Partial | undefined; /** * The system prop that allows defining system overrides as well as additional CSS styles. */ @@ -231,21 +179,6 @@ export interface TooltipProps * Tooltip title. Zero-length titles string, undefined, null and false are never displayed. */ title: React.ReactNode; - /** - * The component used for the transition. - * [Follow this guide](https://mui.com/material-ui/transitions/#transitioncomponent-prop) to learn more about the requirements for this component. - * @deprecated use the `slots.transition` prop instead. This prop will be removed in a future major release. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details. - */ - TransitionComponent?: - | React.JSXElementConstructor }> - | undefined; - /** - * Props applied to the transition element. - * By default, the element is based on this [`Transition`](https://reactcommunity.org/react-transition-group/transition/) component. - * @deprecated use the `slotProps.transition` prop instead. This prop will be removed in a future major release. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details. - * @default {} - */ - TransitionProps?: TransitionProps | undefined; } export interface TooltipOwnerState extends TooltipProps {} diff --git a/packages/mui-material/src/Tooltip/Tooltip.js b/packages/mui-material/src/Tooltip/Tooltip.js index 890945aa5215bd..68e397b0855f62 100644 --- a/packages/mui-material/src/Tooltip/Tooltip.js +++ b/packages/mui-material/src/Tooltip/Tooltip.js @@ -308,15 +308,12 @@ function composeEventHandler(handler, eventHandler) { }; } -// TODO v6: Remove PopperComponent, PopperProps, TransitionComponent and TransitionProps. const Tooltip = React.forwardRef(function Tooltip(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiTooltip' }); const { arrow = false, children: childrenProp, classes: classesProp, - components = {}, - componentsProps = {}, describeChild = false, disableFocusListener = false, disableHoverListener = false, @@ -333,13 +330,9 @@ const Tooltip = React.forwardRef(function Tooltip(inProps, ref) { onOpen, open: openProp, placement = 'bottom', - PopperComponent: PopperComponentProp, - PopperProps = {}, slotProps = {}, slots = {}, title, - TransitionComponent: TransitionComponentProp, - TransitionProps, ...other } = props; @@ -670,7 +663,6 @@ const Tooltip = React.forwardRef(function Tooltip(inProps, ref) { arrow, disableInteractive, placement, - PopperComponentProp, touch: ignoreNonTouchEvents.current, }; @@ -688,42 +680,24 @@ const Tooltip = React.forwardRef(function Tooltip(inProps, ref) { }, ]; - if (PopperProps.popperOptions?.modifiers) { - tooltipModifiers = tooltipModifiers.concat(PopperProps.popperOptions.modifiers); - } - if (resolvedPopperProps?.popperOptions?.modifiers) { tooltipModifiers = tooltipModifiers.concat(resolvedPopperProps.popperOptions.modifiers); } return { - ...PopperProps.popperOptions, ...resolvedPopperProps?.popperOptions, modifiers: tooltipModifiers, }; - }, [arrowRef, PopperProps.popperOptions, resolvedPopperProps?.popperOptions]); + }, [arrowRef, resolvedPopperProps?.popperOptions]); const classes = useUtilityClasses(ownerState); - const resolvedTransitionProps = - typeof slotProps.transition === 'function' - ? slotProps.transition(ownerState) - : slotProps.transition; const externalForwardedProps = { - slots: { - popper: components.Popper, - transition: components.Transition ?? TransitionComponentProp, - tooltip: components.Tooltip, - arrow: components.Arrow, - ...slots, - }, + slots, slotProps: { - arrow: slotProps.arrow ?? componentsProps.arrow, - popper: { ...PopperProps, ...(resolvedPopperProps ?? componentsProps.popper) }, // resolvedPopperProps can be spread because it's already an object - tooltip: slotProps.tooltip ?? componentsProps.tooltip, - transition: { - ...TransitionProps, - ...(resolvedTransitionProps ?? componentsProps.transition), - }, + arrow: slotProps.arrow, + popper: resolvedPopperProps, + tooltip: slotProps.tooltip, + transition: slotProps.transition, }, }; @@ -731,7 +705,7 @@ const Tooltip = React.forwardRef(function Tooltip(inProps, ref) { elementType: TooltipPopper, externalForwardedProps, ownerState, - className: clsx(classes.popper, PopperProps?.className), + className: classes.popper, }); const [TransitionSlot, transitionSlotProps] = useSlot('transition', { @@ -759,7 +733,7 @@ const Tooltip = React.forwardRef(function Tooltip(inProps, ref) { {React.cloneElement(children, childrenProps)} ', () => { refInstanceof: window.HTMLButtonElement, testRootOverrides: { slotName: 'popper', slotClassName: classes.popper }, testDeepOverrides: { slotName: 'tooltip', slotClassName: classes.tooltip }, - testLegacyComponentsProp: true, slots: { popper: { expectedClassName: classes.popper, @@ -293,7 +292,13 @@ describe('', () => { } render( - + @@ -310,7 +315,9 @@ describe('', () => { , @@ -550,7 +561,9 @@ describe('', () => { enterDelay={111} enterNextDelay={30} leaveDelay={5} - TransitionProps={{ timeout: 6 }} + slotProps={{ + transition: { timeout: 6 }, + }} > @@ -813,78 +832,6 @@ describe('', () => { expect(screen.getByTestId('popper')).not.to.equal(null); }); - it('should merge popperOptions with arrow modifier', () => { - const popperRef = React.createRef(); - render( - - - , - ); - - const appliedArrowModifier = popperRef.current.state.orderedModifiers.find( - (modifier) => modifier.name === 'arrow', - ); - - expect(appliedArrowModifier).not.to.equal(undefined); - expect(appliedArrowModifier.enabled).to.equal(true); - expect(appliedArrowModifier.options.padding).to.equal(8); - }); - - it('should merge popperOptions with custom modifier', () => { - const popperRef = React.createRef(); - render( - {}, - }, - ], - }, - }} - > - - , - ); - - const appliedComputeStylesModifier = popperRef.current.state.orderedModifiers.find( - (modifier) => modifier.name === 'foo', - ); - - expect(appliedComputeStylesModifier).not.to.equal(undefined); - }); - }); - - describe('prop: slotProps.popper', () => { it('should merge popperOptions with arrow modifier', () => { const popperRef = React.createRef(); render( @@ -1032,7 +979,9 @@ describe('', () => { onClose={() => eventLog.push('close')} open title="Some information" - TransitionProps={{ timeout: transitionTimeout }} + slotProps={{ + transition: { timeout: transitionTimeout }, + }} > - , - ); - expect(screen.getByTestId('CustomPopper')).toBeVisible(); - }); - }); - describe('prop: followCursor', () => { it('should use the position of the mouse', async function test() { const x = 50; @@ -1206,7 +1141,9 @@ describe('', () => { placement="bottom-end" open followCursor - PopperProps={{ 'data-testid': 'popper' }} + slotProps={{ + popper: { 'data-testid': 'popper' }, + }} > - , - ); - expect(screen.getByTestId('CustomPopper')).toBeVisible(); - }); - - it('can render a different Tooltip component', () => { - const CustomTooltip = React.forwardRef((props, ref) => ( -
- )); - render( - - - , - ); - expect(screen.getByTestId('CustomTooltip')).toBeVisible(); - }); - - it('can render a different Arrow component', () => { - const CustomArrow = React.forwardRef((props, ref) => ( -
- )); - render( - - - , - ); - expect(screen.getByTestId('CustomArrow')).toBeVisible(); - }); - }); - - describe('prop: componentsProps', () => { - it('can provide custom props for the inner Popper component', () => { - render( - - - , - ); - expect(screen.getByTestId('CustomPopper')).toBeVisible(); - }); - - it('can provide custom props for the inner Tooltip component', () => { - render( - - - , - ); - expect(screen.getByTestId('CustomTooltip')).toBeVisible(); - }); - - it('can provide custom props for the inner Arrow component', () => { - render( - - - , - ); - expect(screen.getByTestId('CustomArrow')).toBeVisible(); - }); - }); - describe('prop: slots', () => { it('can render a different Popper component', () => { function CustomPopper() { @@ -1402,7 +1247,9 @@ describe('', () => { enterDelay={enterDelay} leaveTouchDelay={leaveTouchDelay} title="Hello World" - TransitionProps={{ timeout: transitionTimeout }} + slotProps={{ + transition: { timeout: transitionTimeout }, + }} > , @@ -1443,7 +1290,9 @@ describe('', () => { enterDelay={enterDelay} leaveTouchDelay={leaveTouchDelay} title="Hello World" - TransitionProps={{ timeout: transitionTimeout }} + slotProps={{ + transition: { timeout: transitionTimeout }, + }} > , @@ -1459,45 +1308,19 @@ describe('', () => { }); describe('className', () => { - it('should allow className from PopperProps', () => { + it('should allow className from slotProps.popper', () => { render( - - , - ); - - expect(screen.getByTestId('popper')).to.have.class('my-class'); - }); - - it('should allow className from componentsProps.popper', () => { - render( - , ); - expect(screen.getByTestId('popper')).to.have.class('my-class'); - }); - it('should apply both the className from PopperProps and componentsProps.popper if both are passed', () => { - render( - - - , - ); - expect(screen.getByTestId('popper')).to.have.class('my-class-2'); expect(screen.getByTestId('popper')).to.have.class('my-class'); }); });