Skip to content

Commit

Permalink
[material-ui][Accordion] Deprecate *Props props and classes for v6 (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
DiegoAndai committed Jan 16, 2024
1 parent d12b654 commit e6af147
Show file tree
Hide file tree
Showing 14 changed files with 650 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export default function AccordionTransition() {
<Accordion
expanded={expanded}
onChange={handleExpansion}
TransitionComponent={Fade}
TransitionProps={{ timeout: 200 }}
slots={{ transition: Fade }}
slotProps={{ transition: { timeout: 400 } }}
sx={{
'& .MuiAccordion-region': { height: expanded ? 'auto' : 0 },
'& .MuiAccordionDetails-root': { display: expanded ? 'block' : 'none' },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import Accordion, { AccordionProps } from '@mui/material/Accordion';
import Accordion, { AccordionSlots } from '@mui/material/Accordion';
import AccordionSummary from '@mui/material/AccordionSummary';
import AccordionDetails from '@mui/material/AccordionDetails';
import Typography from '@mui/material/Typography';
Expand All @@ -18,8 +18,8 @@ export default function AccordionTransition() {
<Accordion
expanded={expanded}
onChange={handleExpansion}
TransitionComponent={Fade as AccordionProps['TransitionComponent']}
TransitionProps={{ timeout: 200 }}
slots={{ transition: Fade as AccordionSlots['transition'] }}
slotProps={{ transition: { timeout: 400 } }}
sx={{
'& .MuiAccordion-region': { height: expanded ? 'auto' : 0 },
'& .MuiAccordionDetails-root': { display: expanded ? 'block' : 'none' },
Expand Down
6 changes: 3 additions & 3 deletions docs/data/material/components/accordion/accordion.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Use the `defaultExpanded` prop on the Accordion component to have it opened by d

### Transition

Use the `TransitionComponent` and `TransitionProps` props to change the Accordion's default transition.
Use the `slots.transition` and `slotProps.transition` props to change the Accordion's default transition.

{{"demo": "AccordionTransition.js", "bg": true}}

Expand Down Expand Up @@ -89,10 +89,10 @@ The demo below also shows a bit of visual customziation.
The Accordion content is mounted by default even if it's not expanded.
This default behavior has server-side rendering and SEO in mind.

If you render the Accordion Details with a big component tree nested inside, or if you have many Accordions, you may want to change this behavior by setting `unmountOnExit` to `true` inside the `TransitionProps` prop to improve performance:
If you render the Accordion Details with a big component tree nested inside, or if you have many Accordions, you may want to change this behavior by setting `unmountOnExit` to `true` inside the `slotProps.transition` prop to improve performance:

```jsx
<Accordion TransitionProps={{ unmountOnExit: true }} />
<Accordion slotProps={{ transition: { unmountOnExit: true } }} />
```

## Accessibility
Expand Down
3 changes: 2 additions & 1 deletion docs/pages/material-ui/api/accordion-summary.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"key": "contentGutters",
"className": "MuiAccordionSummary-contentGutters",
"description": "Styles applied to the children wrapper element unless `disableGutters={true}`.",
"isGlobal": false
"isGlobal": false,
"isDeprecated": true
},
{
"key": "disabled",
Expand Down
28 changes: 26 additions & 2 deletions docs/pages/material-ui/api/accordion.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
"describedArgs": ["event", "expanded"]
}
},
"slotProps": {
"type": { "name": "shape", "description": "{ transition?: func<br>&#124;&nbsp;object }" },
"default": "{}"
},
"slots": {
"type": { "name": "shape", "description": "{ transition?: elementType }" },
"default": "{}"
},
"square": { "type": { "name": "bool" }, "default": "false" },
"sx": {
"type": {
Expand All @@ -21,14 +29,30 @@
},
"additionalInfo": { "sx": true }
},
"TransitionComponent": { "type": { "name": "elementType" }, "default": "Collapse" },
"TransitionProps": { "type": { "name": "object" } }
"TransitionComponent": {
"type": { "name": "elementType" },
"deprecated": true,
"deprecationInfo": "Use <code>slots.transition</code> instead. This prop will be removed in v7."
},
"TransitionProps": {
"type": { "name": "object" },
"deprecated": true,
"deprecationInfo": "Use <code>slotProps.transition</code> instead. This prop will be removed in v7."
}
},
"name": "Accordion",
"imports": [
"import Accordion from '@mui/material/Accordion';",
"import { Accordion } from '@mui/material';"
],
"slots": [
{
"name": "transition",
"description": "The component that renders the transition.\n[Follow this guide](/material-ui/transitions/#transitioncomponent-prop) to learn more about the requirements for this component.",
"default": "Collapse",
"class": null
}
],
"classes": [
{
"key": "disabled",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"contentGutters": {
"description": "Styles applied to {{nodeName}} unless {{conditions}}.",
"nodeName": "the children wrapper element",
"conditions": "<code>disableGutters={true}</code>"
"conditions": "<code>disableGutters={true}</code>",
"deprecationInfo": "Combine the <a href=\"/material-ui/api/accordion-summary/#AccordionSummary-classes-gutters\">.MuiAccordionSummary-gutters</a> and <a href=\"/material-ui/api/accordion-summary/#AccordionSummary-classes-content\">.MuiAccordionSummary-content</a> classes instead."
},
"disabled": {
"description": "State class applied to {{nodeName}} if {{conditions}}.",
Expand Down
5 changes: 5 additions & 0 deletions docs/translations/api-docs/accordion/accordion.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
"expanded": "The <code>expanded</code> state of the accordion."
}
},
"slotProps": { "description": "The props used for each slot inside." },
"slots": { "description": "The components used for each slot inside." },
"square": { "description": "If <code>true</code>, rounded corners are disabled." },
"sx": {
"description": "The system prop that allows defining system overrides as well as additional CSS styles."
Expand Down Expand Up @@ -56,5 +58,8 @@
"nodeName": "the root element",
"conditions": "<code>square={true}</code>"
}
},
"slotDescriptions": {
"transition": "The component that renders the transition.\n[Follow this guide](/material-ui/transitions/#transitioncomponent-prop) to learn more about the requirements for this component."
}
}
32 changes: 30 additions & 2 deletions packages/mui-material/src/Accordion/Accordion.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,31 @@ import { TransitionProps } from '../transitions/transition';
import { AccordionClasses } from './accordionClasses';
import { OverridableComponent, OverrideProps } from '../OverridableComponent';
import { ExtendPaperTypeMap } from '../Paper/Paper';
import { CreateSlotsAndSlotProps, SlotProps } from '../utils/types';

export interface AccordionSlots {
/**
* The component that renders the transition.
* [Follow this guide](/material-ui/transitions/#transitioncomponent-prop) to learn more about the requirements for this component.
* @default Collapse
*/
transition?: React.JSXElementConstructor<
TransitionProps & { children?: React.ReactElement<any, any> }
>;
}

export interface AccordionTransitionSlotPropsOverrides {}

export type AccordionSlotsAndSlotProps = CreateSlotsAndSlotProps<
AccordionSlots,
{
transition: SlotProps<
React.ElementType<TransitionProps>,
AccordionTransitionSlotPropsOverrides,
AccordionOwnerState
>;
}
>;

export type AccordionTypeMap<
AdditionalProps = {},
Expand Down Expand Up @@ -54,17 +79,18 @@ export type AccordionTypeMap<
/**
* The component used for the transition.
* [Follow this guide](/material-ui/transitions/#transitioncomponent-prop) to learn more about the requirements for this component.
* @default Collapse
* @deprecated Use `slots.transition` instead. This prop will be removed in v7.
*/
TransitionComponent?: React.JSXElementConstructor<
TransitionProps & { children?: React.ReactElement<any, any> }
>;
/**
* Props applied to the transition element.
* By default, the element is based on this [`Transition`](http://reactcommunity.org/react-transition-group/transition/) component.
* @deprecated Use `slotProps.transition` instead. This prop will be removed in v7.
*/
TransitionProps?: TransitionProps;
};
} & AccordionSlotsAndSlotProps;
defaultComponent: RootComponent;
},
'onChange' | 'classes'
Expand All @@ -90,4 +116,6 @@ export type AccordionProps<
component?: React.ElementType;
};

export interface AccordionOwnerState extends AccordionProps {}

export default Accordion;
42 changes: 37 additions & 5 deletions packages/mui-material/src/Accordion/Accordion.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Collapse from '../Collapse';
import Paper from '../Paper';
import AccordionContext from './AccordionContext';
import useControlled from '../utils/useControlled';
import useSlot from '../utils/useSlot';
import accordionClasses, { getAccordionUtilityClass } from './accordionClasses';

const useUtilityClasses = (ownerState) => {
Expand Down Expand Up @@ -126,8 +127,10 @@ const Accordion = React.forwardRef(function Accordion(inProps, ref) {
expanded: expandedProp,
onChange,
square = false,
TransitionComponent = Collapse,
TransitionProps,
slots = {},
slotProps = {},
TransitionComponent: TransitionComponentProp,
TransitionProps: TransitionPropsProp,
...other
} = props;

Expand Down Expand Up @@ -165,6 +168,20 @@ const Accordion = React.forwardRef(function Accordion(inProps, ref) {

const classes = useUtilityClasses(ownerState);

const backwardCompatibleSlots = { transition: TransitionComponentProp, ...slots };
const backwardCompatibleSlotProps = { transition: TransitionPropsProp, ...slotProps };

const [TransitionSlot, transitionProps] = useSlot('transition', {
elementType: Collapse,
externalForwardedProps: {
slots: backwardCompatibleSlots,
slotProps: backwardCompatibleSlotProps,
},
ownerState,
});

delete transitionProps.ownerState;

return (
<AccordionRoot
className={clsx(classes.root, className)}
Expand All @@ -174,7 +191,7 @@ const Accordion = React.forwardRef(function Accordion(inProps, ref) {
{...other}
>
<AccordionContext.Provider value={contextValue}>{summary}</AccordionContext.Provider>
<TransitionComponent in={expanded} timeout="auto" {...TransitionProps}>
<TransitionSlot in={expanded} timeout="auto" {...transitionProps}>
<div
aria-labelledby={summary.props.id}
id={summary.props['aria-controls']}
Expand All @@ -183,7 +200,7 @@ const Accordion = React.forwardRef(function Accordion(inProps, ref) {
>
{children}
</div>
</TransitionComponent>
</TransitionSlot>
</AccordionRoot>
);
});
Expand Down Expand Up @@ -246,6 +263,20 @@ Accordion.propTypes /* remove-proptypes */ = {
* @param {boolean} expanded The `expanded` state of the accordion.
*/
onChange: PropTypes.func,
/**
* The props used for each slot inside.
* @default {}
*/
slotProps: PropTypes.shape({
transition: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
}),
/**
* The components used for each slot inside.
* @default {}
*/
slots: PropTypes.shape({
transition: PropTypes.elementType,
}),
/**
* If `true`, rounded corners are disabled.
* @default false
Expand All @@ -262,12 +293,13 @@ Accordion.propTypes /* remove-proptypes */ = {
/**
* The component used for the transition.
* [Follow this guide](/material-ui/transitions/#transitioncomponent-prop) to learn more about the requirements for this component.
* @default Collapse
* @deprecated Use `slots.transition` instead. This prop will be removed in v7.
*/
TransitionComponent: PropTypes.elementType,
/**
* Props applied to the transition element.
* By default, the element is based on this [`Transition`](http://reactcommunity.org/react-transition-group/transition/) component.
* @deprecated Use `slotProps.transition` instead. This prop will be removed in v7.
*/
TransitionProps: PropTypes.object,
};
Expand Down
41 changes: 41 additions & 0 deletions packages/mui-material/src/Accordion/Accordion.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ describe('<Accordion />', () => {
refInstanceof: window.HTMLDivElement,
muiName: 'MuiAccordion',
testVariantProps: { variant: 'rounded' },
slots: {
transition: {
testWithElement: null,
},
},
skip: ['componentProp', 'componentsProp'],
}));

Expand Down Expand Up @@ -210,4 +215,40 @@ describe('<Accordion />', () => {
'MUI: A component is changing the uncontrolled expanded state of Accordion to be controlled.',
);
});

describe('prop: TransitionProps', () => {
it('should apply properties to the Transition component', () => {
const { getByTestId } = render(
<Accordion TransitionProps={{ 'data-testid': 'transition-testid' }}>
{minimalChildren}
</Accordion>,
);

expect(getByTestId('transition-testid')).not.to.equal(null);
});
});

describe('details unmounting behavior', () => {
it('does not unmount by default', () => {
const { queryByTestId } = render(
<Accordion expanded={false}>
<AccordionSummary>Summary</AccordionSummary>
<div data-testid="details">Details</div>
</Accordion>,
);

expect(queryByTestId('details')).not.to.equal(null);
});

it('unmounts if opted in via slotProps.transition', () => {
const { queryByTestId } = render(
<Accordion expanded={false} slotProps={{ transition: { unmountOnExit: true } }}>
<AccordionSummary>Summary</AccordionSummary>
<div data-testid="details">Details</div>
</Accordion>,
);

expect(queryByTestId('details')).to.equal(null);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ export interface AccordionSummaryClasses {
disabled: string;
/** Styles applied to the root element unless `disableGutters={true}`. */
gutters: string;
/** Styles applied to the children wrapper element unless `disableGutters={true}`. */
/**
* Styles applied to the children wrapper element unless `disableGutters={true}`.
* @deprecated Combine the [.MuiAccordionSummary-gutters](/material-ui/api/accordion-summary/#AccordionSummary-classes-gutters) and [.MuiAccordionSummary-content](/material-ui/api/accordion-summary/#AccordionSummary-classes-content) classes instead.
*/
contentGutters: string;
/** Styles applied to the children wrapper element. */
content: string;
Expand Down
33 changes: 33 additions & 0 deletions packages/mui-material/src/utils/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { SxProps } from '@mui/system';
import { SlotComponentProps } from '@mui/base';

export type SlotCommonProps = {
component?: React.ElementType;
sx?: SxProps;
};

export type SlotProps<
TSlotComponent extends React.ElementType,
TOverrides,
TOwnerState,
> = SlotComponentProps<TSlotComponent, SlotCommonProps & TOverrides, TOwnerState>;

/**
* Use the keys of `Slots` to make sure that K contains all of the keys
*
* @example CreateSlotsAndSlotProps<{ root: React.ElementType, decorator: React.ElementType }, { root: ..., decorator: ... }>
*/
export type CreateSlotsAndSlotProps<Slots, K extends Record<keyof Slots, any>> = {
/**
* The components used for each slot inside.
* @default {}
*/
slots?: Slots;
/**
* The props used for each slot inside.
* @default {}
*/
slotProps?: {
[P in keyof K]?: K[P];
};
};

0 comments on commit e6af147

Please sign in to comment.