diff --git a/docs/pages/api-docs/paper.json b/docs/pages/api-docs/paper.json
index 280490c468c082..75773a65810577 100644
--- a/docs/pages/api-docs/paper.json
+++ b/docs/pages/api-docs/paper.json
@@ -5,6 +5,7 @@
"component": { "type": { "name": "elementType" } },
"elevation": { "type": { "name": "number" }, "default": "1" },
"square": { "type": { "name": "bool" } },
+ "sx": { "type": { "name": "object" } },
"variant": {
"type": {
"name": "union",
@@ -54,5 +55,5 @@
"filename": "/packages/material-ui/src/Paper/Paper.js",
"inheritance": null,
"demos": "
",
- "styledComponent": false
+ "styledComponent": true
}
diff --git a/docs/translations/api-docs/paper/paper.json b/docs/translations/api-docs/paper/paper.json
index 746579030f3f8d..3670a161bee872 100644
--- a/docs/translations/api-docs/paper/paper.json
+++ b/docs/translations/api-docs/paper/paper.json
@@ -6,6 +6,7 @@
"component": "The component used for the root node. Either a string to use a HTML element or a component.",
"elevation": "Shadow depth, corresponds to dp
in the spec. It accepts values between 0 and 24 inclusive.",
"square": "If true
, rounded corners are disabled.",
+ "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details.",
"variant": "The variant to use."
},
"classDescriptions": {
diff --git a/framer/scripts/framerConfig.js b/framer/scripts/framerConfig.js
index fb02f439b69a3c..526d4d294a3182 100644
--- a/framer/scripts/framerConfig.js
+++ b/framer/scripts/framerConfig.js
@@ -225,6 +225,7 @@ export const componentSettings = {
},
Paper: {
ignoredProps: [
+ 'sx',
// FIXME: `Union`
'variant',
],
diff --git a/packages/material-ui/src/MobileStepper/MobileStepper.test.js b/packages/material-ui/src/MobileStepper/MobileStepper.test.js
index 4013e21ad464db..f8ee1b351728f0 100644
--- a/packages/material-ui/src/MobileStepper/MobileStepper.test.js
+++ b/packages/material-ui/src/MobileStepper/MobileStepper.test.js
@@ -9,7 +9,7 @@ import {
} from 'test/utils';
import KeyboardArrowLeft from '../internal/svg-icons/KeyboardArrowLeft';
import KeyboardArrowRight from '../internal/svg-icons/KeyboardArrowRight';
-import Paper from '../Paper';
+import Paper, { paperClasses } from '../Paper';
import Button from '../Button/Button';
import MobileStepper from './MobileStepper';
@@ -47,7 +47,6 @@ describe('', () => {
it('should render a Paper with 0 elevation', () => {
const { container } = render();
- const paperClasses = getClasses();
expect(container.firstChild).to.have.class(paperClasses.elevation0);
});
diff --git a/packages/material-ui/src/Paper/Paper.d.ts b/packages/material-ui/src/Paper/Paper.d.ts
index 010593284ccd22..0b3d40a16a116e 100644
--- a/packages/material-ui/src/Paper/Paper.d.ts
+++ b/packages/material-ui/src/Paper/Paper.d.ts
@@ -1,5 +1,7 @@
import * as React from 'react';
+import { SxProps } from '@material-ui/system';
import { OverridableStringUnion } from '@material-ui/types';
+import { Theme } from '../styles';
import { InternalStandardProps as StandardProps } from '..';
export interface PaperPropsVariantOverrides {}
@@ -64,6 +66,10 @@ export interface PaperProps extends StandardProps;
/**
* The variant to use.
* @default 'elevation'
diff --git a/packages/material-ui/src/Paper/Paper.js b/packages/material-ui/src/Paper/Paper.js
index a0ef15ad33d2f3..c0038a9dd071df 100644
--- a/packages/material-ui/src/Paper/Paper.js
+++ b/packages/material-ui/src/Paper/Paper.js
@@ -1,42 +1,71 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
-import { useThemeVariants } from '@material-ui/styles';
-import withStyles from '../styles/withStyles';
+import { deepmerge } from '@material-ui/utils';
+import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
+import experimentalStyled from '../styles/experimentalStyled';
+import useThemeProps from '../styles/useThemeProps';
import useTheme from '../styles/useTheme';
+import { getPaperUtilityClass } from './paperClasses';
-export const styles = (theme) => {
- const elevations = {};
- theme.shadows.forEach((shadow, index) => {
- elevations[`elevation${index}`] = {
- boxShadow: shadow,
- };
+const overridesResolver = (props, styles) => {
+ const { styleProps } = props;
+
+ return deepmerge(styles.root || {}, {
+ ...styles[styleProps.variant],
+ ...(!styleProps.square && styles.rounded),
+ ...(styleProps.variant === 'elevation' && styles[`elevation${styleProps.elevation}`]),
});
+};
+
+const useUtilityClasses = (styleProps) => {
+ const { square, elevation, variant, classes } = styleProps;
+ const slots = {
+ root: [
+ 'root',
+ variant,
+ !square && 'rounded',
+ variant === 'elevation' && `elevation${elevation}`,
+ ],
+ };
+
+ return composeClasses({ slots, classes, getUtilityClass: getPaperUtilityClass });
+};
+
+const PaperRoot = experimentalStyled(
+ 'div',
+ {},
+ {
+ name: 'MuiPaper',
+ slot: 'Root',
+ overridesResolver,
+ },
+)(({ theme, styleProps }) => {
return {
/* Styles applied to the root element. */
- root: {
- backgroundColor: theme.palette.background.paper,
- color: theme.palette.text.primary,
- transition: theme.transitions.create('box-shadow'),
- },
+ backgroundColor: theme.palette.background.paper,
+ color: theme.palette.text.primary,
+ transition: theme.transitions.create('box-shadow'),
/* Styles applied to the root element unless `square={true}`. */
- rounded: {
+ ...(!styleProps.square && {
borderRadius: theme.shape.borderRadius,
- },
+ }),
/* Styles applied to the root element if `variant="outlined"`. */
- outlined: {
+ ...(styleProps.variant === 'outlined' && {
border: `1px solid ${theme.palette.divider}`,
- },
+ }),
/* Styles applied to the root element if `variant="elevation"`. */
- elevation: {},
- ...elevations,
+ ...(styleProps.variant === 'elevation' && {
+ boxShadow: theme.shadows[styleProps.elevation],
+ }),
};
-};
+});
+
+const Paper = React.forwardRef(function Paper(inProps, ref) {
+ const props = useThemeProps({ props: inProps, name: 'MuiPaper' });
-const Paper = React.forwardRef(function Paper(props, ref) {
const {
- classes,
className,
component: Component = 'div',
square = false,
@@ -45,16 +74,14 @@ const Paper = React.forwardRef(function Paper(props, ref) {
...other
} = props;
- const themeVariantsClasses = useThemeVariants(
- {
- ...props,
- component: Component,
- square,
- elevation,
- variant,
- },
- 'MuiPaper',
- );
+ const styleProps = {
+ ...props,
+ variant,
+ elevation,
+ square,
+ };
+
+ const classes = useUtilityClasses(styleProps);
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line react-hooks/rules-of-hooks
@@ -70,17 +97,10 @@ const Paper = React.forwardRef(function Paper(props, ref) {
}
return (
-
@@ -120,6 +140,10 @@ Paper.propTypes = {
* @default false
*/
square: PropTypes.bool,
+ /**
+ * The system prop that allows defining system overrides as well as additional CSS styles.
+ */
+ sx: PropTypes.object,
/**
* The variant to use.
* @default 'elevation'
@@ -130,4 +154,4 @@ Paper.propTypes = {
]),
};
-export default withStyles(styles, { name: 'MuiPaper' })(Paper);
+export default Paper;
diff --git a/packages/material-ui/src/Paper/Paper.test.js b/packages/material-ui/src/Paper/Paper.test.js
index 661a16b859b531..b26dc6be5738c5 100644
--- a/packages/material-ui/src/Paper/Paper.test.js
+++ b/packages/material-ui/src/Paper/Paper.test.js
@@ -1,24 +1,24 @@
import * as React from 'react';
import { expect } from 'chai';
-import { createClientRender, getClasses, createMount, describeConformance } from 'test/utils';
+import { createClientRender, createMount, describeConformanceV5 } from 'test/utils';
import Paper from './Paper';
+import classes from './paperClasses';
import { createMuiTheme, ThemeProvider } from '../styles';
describe('', () => {
const mount = createMount();
const render = createClientRender();
- let classes;
- before(() => {
- classes = getClasses();
- });
-
- describeConformance(, () => ({
+ describeConformanceV5(, () => ({
classes,
inheritComponent: 'div',
mount,
+ muiName: 'MuiPaper',
refInstanceof: window.HTMLDivElement,
testComponentPropWith: 'header',
+ testVariantProps: { variant: 'rounded' },
+ testStateOverrides: { prop: 'elevation', value: 10, styleKey: 'elevation10' },
+ skip: ['componentsProp'],
}));
describe('prop: square', () => {
diff --git a/packages/material-ui/src/Paper/index.d.ts b/packages/material-ui/src/Paper/index.d.ts
index d40fffd9883330..238f99f35769ca 100644
--- a/packages/material-ui/src/Paper/index.d.ts
+++ b/packages/material-ui/src/Paper/index.d.ts
@@ -1,2 +1,4 @@
export { default } from './Paper';
export * from './Paper';
+export { default as paperClasses } from './paperClasses';
+export * from './paperClasses';
diff --git a/packages/material-ui/src/Paper/index.js b/packages/material-ui/src/Paper/index.js
index 559d1a73e5034f..cd47085da76189 100644
--- a/packages/material-ui/src/Paper/index.js
+++ b/packages/material-ui/src/Paper/index.js
@@ -1 +1,3 @@
export { default } from './Paper';
+export { default as paperClasses } from './paperClasses';
+export * from './paperClasses';
diff --git a/packages/material-ui/src/Paper/paperClasses.d.ts b/packages/material-ui/src/Paper/paperClasses.d.ts
new file mode 100644
index 00000000000000..405cf4a811d504
--- /dev/null
+++ b/packages/material-ui/src/Paper/paperClasses.d.ts
@@ -0,0 +1,37 @@
+export interface PaperClasses {
+ root: string;
+ rounded: string;
+ outlined: string;
+ elevation: string;
+ elevation0: string;
+ elevation1: string;
+ elevation2: string;
+ elevation3: string;
+ elevation4: string;
+ elevation5: string;
+ elevation6: string;
+ elevation7: string;
+ elevation8: string;
+ elevation9: string;
+ elevation10: string;
+ elevation11: string;
+ elevation12: string;
+ elevation13: string;
+ elevation14: string;
+ elevation15: string;
+ elevation16: string;
+ elevation17: string;
+ elevation18: string;
+ elevation19: string;
+ elevation20: string;
+ elevation21: string;
+ elevation22: string;
+ elevation23: string;
+ elevation24: string;
+}
+
+declare const paperClasses: PaperClasses;
+
+export function getPaperUtilityClass(slot: string): string;
+
+export default paperClasses;
diff --git a/packages/material-ui/src/Paper/paperClasses.js b/packages/material-ui/src/Paper/paperClasses.js
new file mode 100644
index 00000000000000..9a36c094f70f9b
--- /dev/null
+++ b/packages/material-ui/src/Paper/paperClasses.js
@@ -0,0 +1,39 @@
+import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled';
+
+export function getPaperUtilityClass(slot) {
+ return generateUtilityClass('MuiPaper', slot);
+}
+
+const paperClasses = generateUtilityClasses('MuiPaper', [
+ 'root',
+ 'rounded',
+ 'outlined',
+ 'elevation',
+ 'elevation0',
+ 'elevation1',
+ 'elevation2',
+ 'elevation3',
+ 'elevation4',
+ 'elevation5',
+ 'elevation6',
+ 'elevation7',
+ 'elevation8',
+ 'elevation9',
+ 'elevation10',
+ 'elevation11',
+ 'elevation12',
+ 'elevation13',
+ 'elevation14',
+ 'elevation15',
+ 'elevation16',
+ 'elevation17',
+ 'elevation18',
+ 'elevation19',
+ 'elevation20',
+ 'elevation21',
+ 'elevation22',
+ 'elevation23',
+ 'elevation24',
+]);
+
+export default paperClasses;