diff --git a/docs/pages/material-ui/api/collapse.json b/docs/pages/material-ui/api/collapse.json
index 88adc7e4f91873..539424730bef55 100644
--- a/docs/pages/material-ui/api/collapse.json
+++ b/docs/pages/material-ui/api/collapse.json
@@ -19,6 +19,20 @@
"type": { "name": "enum", "description": "'horizontal'
| 'vertical'" },
"default": "'vertical'"
},
+ "slotProps": {
+ "type": {
+ "name": "shape",
+ "description": "{ root?: func
| object, wrapper?: func
| object, wrapperInner?: func
| object }"
+ },
+ "default": "{}"
+ },
+ "slots": {
+ "type": {
+ "name": "shape",
+ "description": "{ root?: elementType, wrapper?: elementType, wrapperInner?: elementType }"
+ },
+ "default": "{}"
+ },
"sx": {
"type": {
"name": "union",
@@ -39,6 +53,26 @@
"import Collapse from '@mui/material/Collapse';",
"import { Collapse } from '@mui/material';"
],
+ "slots": [
+ {
+ "name": "root",
+ "description": "The component that renders the root.",
+ "default": "'div'",
+ "class": "MuiCollapse-root"
+ },
+ {
+ "name": "wrapper",
+ "description": "The component that renders the wrapper.",
+ "default": "'div'",
+ "class": "MuiCollapse-wrapper"
+ },
+ {
+ "name": "wrapperInner",
+ "description": "The component that renders the inner wrapper.",
+ "default": "'div'",
+ "class": "MuiCollapse-wrapperInner"
+ }
+ ],
"classes": [
{
"key": "entered",
@@ -57,24 +91,6 @@
"className": "MuiCollapse-horizontal",
"description": "State class applied to the root element if `orientation=\"horizontal\"`.",
"isGlobal": false
- },
- {
- "key": "root",
- "className": "MuiCollapse-root",
- "description": "Styles applied to the root element.",
- "isGlobal": false
- },
- {
- "key": "wrapper",
- "className": "MuiCollapse-wrapper",
- "description": "Styles applied to the outer wrapper element.",
- "isGlobal": false
- },
- {
- "key": "wrapperInner",
- "className": "MuiCollapse-wrapperInner",
- "description": "Styles applied to the inner wrapper element.",
- "isGlobal": false
}
],
"spread": true,
diff --git a/docs/translations/api-docs/collapse/collapse.json b/docs/translations/api-docs/collapse/collapse.json
index f3bcd44dc8b552..3cee03c5880cba 100644
--- a/docs/translations/api-docs/collapse/collapse.json
+++ b/docs/translations/api-docs/collapse/collapse.json
@@ -18,6 +18,8 @@
},
"in": { "description": "If true, the component will transition in." },
"orientation": { "description": "The transition orientation." },
+ "slotProps": { "description": "The props used for each slot inside." },
+ "slots": { "description": "The components used for each slot inside." },
"sx": {
"description": "The system prop that allows defining system overrides as well as additional CSS styles."
},
@@ -40,15 +42,11 @@
"description": "State class applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the root element",
"conditions": "orientation=\"horizontal\""
- },
- "root": { "description": "Styles applied to the root element." },
- "wrapper": {
- "description": "Styles applied to {{nodeName}}.",
- "nodeName": "the outer wrapper element"
- },
- "wrapperInner": {
- "description": "Styles applied to {{nodeName}}.",
- "nodeName": "the inner wrapper element"
}
+ },
+ "slotDescriptions": {
+ "root": "The component that renders the root.",
+ "wrapper": "The component that renders the wrapper.",
+ "wrapperInner": "The component that renders the inner wrapper."
}
}
diff --git a/packages/mui-material/src/Collapse/Collapse.d.ts b/packages/mui-material/src/Collapse/Collapse.d.ts
index bdab394f7fa3fd..46f3ae39a62cc8 100644
--- a/packages/mui-material/src/Collapse/Collapse.d.ts
+++ b/packages/mui-material/src/Collapse/Collapse.d.ts
@@ -1,11 +1,48 @@
import * as React from 'react';
import { SxProps } from '@mui/system';
+import { TransitionStatus } from 'react-transition-group';
import { Theme } from '../styles';
import { InternalStandardProps as StandardProps } from '../internal';
import { TransitionProps } from '../transitions/transition';
import { CollapseClasses } from './collapseClasses';
+import { CreateSlotsAndSlotProps, SlotProps } from '../utils/types';
-export interface CollapseProps extends StandardProps {
+export interface CollapseSlots {
+ /**
+ * The component that renders the root.
+ * @default 'div'
+ */
+ root?: React.ElementType;
+ /**
+ * The component that renders the wrapper.
+ * @default 'div'
+ */
+ wrapper?: React.ElementType;
+ /**
+ * The component that renders the inner wrapper.
+ * @default 'div'
+ */
+ wrapperInner?: React.ElementType;
+}
+
+export interface CollapseRootSlotPropsOverrides {}
+
+export interface CollapseWrapperSlotPropsOverrides {}
+
+export interface CollapseWrapperInnerSlotPropsOverrides {}
+
+export type CollapseSlotsAndSlotProps = CreateSlotsAndSlotProps<
+ CollapseSlots,
+ {
+ root: SlotProps<'div', CollapseRootSlotPropsOverrides, CollapseOwnerState>;
+ wrapper: SlotProps<'div', CollapseWrapperSlotPropsOverrides, CollapseOwnerState>;
+ wrapperInner: SlotProps<'div', CollapseWrapperInnerSlotPropsOverrides, CollapseOwnerState>;
+ }
+>;
+
+export interface CollapseProps
+ extends StandardProps,
+ CollapseSlotsAndSlotProps {
/**
* The content node to be collapsed.
*/
@@ -53,6 +90,10 @@ export interface CollapseProps extends StandardProps
sx?: SxProps;
}
+export interface CollapseOwnerState extends CollapseProps {
+ state: TransitionStatus;
+}
+
/**
* The Collapse transition is used by the
* [Vertical Stepper](https://mui.com/material-ui/react-stepper/#vertical-stepper) StepContent component.
diff --git a/packages/mui-material/src/Collapse/Collapse.js b/packages/mui-material/src/Collapse/Collapse.js
index d401f5fd822f5c..d2766ab7263a3e 100644
--- a/packages/mui-material/src/Collapse/Collapse.js
+++ b/packages/mui-material/src/Collapse/Collapse.js
@@ -12,6 +12,7 @@ import { useDefaultProps } from '../DefaultPropsProvider';
import { duration } from '../styles/createTransitions';
import { getTransitionProps } from '../transitions/utils';
import { useForkRef } from '../utils';
+import useSlot from '../utils/useSlot';
import { getCollapseUtilityClass } from './collapseClasses';
const useUtilityClasses = (ownerState) => {
@@ -149,6 +150,8 @@ const Collapse = React.forwardRef(function Collapse(inProps, ref) {
onExited,
onExiting,
orientation = 'vertical',
+ slots = {},
+ slotProps = {},
style,
timeout = duration.standard,
// eslint-disable-next-line react/prop-types
@@ -292,6 +295,41 @@ const Collapse = React.forwardRef(function Collapse(inProps, ref) {
}
};
+ const externalForwardedProps = {
+ slots,
+ slotProps,
+ component,
+ };
+
+ const [RootSlot, rootSlotProps] = useSlot('root', {
+ ref: handleRef,
+ className: clsx(classes.root, className),
+ elementType: CollapseRoot,
+ externalForwardedProps,
+ ownerState,
+ additionalProps: {
+ style: {
+ [isHorizontal ? 'minWidth' : 'minHeight']: collapsedSize,
+ ...style,
+ },
+ },
+ });
+
+ const [WrapperSlot, wrapperSlotProps] = useSlot('wrapper', {
+ ref: wrapperRef,
+ className: classes.wrapper,
+ elementType: CollapseWrapper,
+ externalForwardedProps,
+ ownerState,
+ });
+
+ const [WrapperInnerSlot, wrapperInnerSlotProps] = useSlot('wrapperInner', {
+ className: classes.wrapperInner,
+ elementType: CollapseWrapperInner,
+ externalForwardedProps,
+ ownerState,
+ });
+
return (
{/* Destructure child props to prevent the component's "ownerState" from being overridden by incomingOwnerState. */}
- {(state, { ownerState: incomingOwnerState, ...restChildProps }) => (
- {
+ const stateOwnerState = { ...ownerState, state };
+ return (
+
-
-
- {children}
-
-
-
- )}
+
+
+ {children}
+
+
+
+ );
+ }}
);
});
@@ -421,6 +446,24 @@ Collapse.propTypes /* remove-proptypes */ = {
* @default 'vertical'
*/
orientation: PropTypes.oneOf(['horizontal', 'vertical']),
+ /**
+ * The props used for each slot inside.
+ * @default {}
+ */
+ slotProps: PropTypes.shape({
+ root: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
+ wrapper: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
+ wrapperInner: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
+ }),
+ /**
+ * The components used for each slot inside.
+ * @default {}
+ */
+ slots: PropTypes.shape({
+ root: PropTypes.elementType,
+ wrapper: PropTypes.elementType,
+ wrapperInner: PropTypes.elementType,
+ }),
/**
* @ignore
*/
diff --git a/packages/mui-material/src/Collapse/Collapse.test.js b/packages/mui-material/src/Collapse/Collapse.test.js
index 24896c949a6a48..d46b25e9cc251b 100644
--- a/packages/mui-material/src/Collapse/Collapse.test.js
+++ b/packages/mui-material/src/Collapse/Collapse.test.js
@@ -1,3 +1,4 @@
+import * as React from 'react';
import { expect } from 'chai';
import { spy, stub } from 'sinon';
import { act, createRenderer } from '@mui/internal-test-utils';
@@ -6,6 +7,16 @@ import { ThemeProvider, createTheme } from '@mui/material/styles';
import Collapse, { collapseClasses as classes } from '@mui/material/Collapse';
import describeConformance from '../../test/describeConformance';
+const CustomCollapse = React.forwardRef(({ ownerState, ...props }, ref) => (
+
+));
+const CustomWrapper = React.forwardRef(({ ownerState, ...props }, ref) => (
+
+));
+const CustomWrapperInner = React.forwardRef(({ ownerState, ...props }, ref) => (
+
+));
+
describe('', () => {
const { clock, render } = createRenderer();
@@ -22,6 +33,14 @@ describe('', () => {
muiName: 'MuiCollapse',
testVariantProps: { orientation: 'horizontal' },
testDeepOverrides: { slotName: 'wrapper', slotClassName: classes.wrapper },
+ slots: {
+ root: { expectedClassName: classes.root, testWithElement: CustomCollapse },
+ wrapper: { expectedClassName: classes.wrapper, testWithElement: CustomWrapper },
+ wrapperInner: {
+ expectedClassName: classes.wrapperInner,
+ testWithElement: CustomWrapperInner,
+ },
+ },
skip: ['componentsProp'],
}));