diff --git a/docs/pages/api-docs/card-header.json b/docs/pages/api-docs/card-header.json
index ec2825b28cf9eb..38d9e3e97f3c8a 100644
--- a/docs/pages/api-docs/card-header.json
+++ b/docs/pages/api-docs/card-header.json
@@ -7,6 +7,7 @@
"disableTypography": { "type": { "name": "bool" } },
"subheader": { "type": { "name": "node" } },
"subheaderTypographyProps": { "type": { "name": "object" } },
+ "sx": { "type": { "name": "object" } },
"title": { "type": { "name": "node" } },
"titleTypographyProps": { "type": { "name": "object" } }
},
@@ -21,6 +22,6 @@
"filename": "/packages/material-ui/src/CardHeader/CardHeader.js",
"inheritance": null,
"demos": "
",
- "styledComponent": false,
+ "styledComponent": true,
"cssComponent": false
}
diff --git a/docs/translations/api-docs/card-header/card-header.json b/docs/translations/api-docs/card-header/card-header.json
index 3c285917a4523d..d18739b747626c 100644
--- a/docs/translations/api-docs/card-header/card-header.json
+++ b/docs/translations/api-docs/card-header/card-header.json
@@ -8,6 +8,7 @@
"disableTypography": "If true
, subheader
and title
won't be wrapped by a Typography component. This can be useful to render an alternative Typography variant by wrapping the title
text, and optional subheader
text with the Typography component.",
"subheader": "The content of the component.",
"subheaderTypographyProps": "These props will be forwarded to the subheader (as long as disableTypography is not true
).",
+ "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details.",
"title": "The content of the component.",
"titleTypographyProps": "These props will be forwarded to the title (as long as disableTypography is not true
)."
},
diff --git a/packages/material-ui/src/CardHeader/CardHeader.d.ts b/packages/material-ui/src/CardHeader/CardHeader.d.ts
index 490cae40d0888f..68404b6fdf9653 100644
--- a/packages/material-ui/src/CardHeader/CardHeader.d.ts
+++ b/packages/material-ui/src/CardHeader/CardHeader.d.ts
@@ -1,6 +1,8 @@
import * as React from 'react';
+import { SxProps } from '@material-ui/system';
import { TypographyProps } from '../Typography';
import { OverridableComponent, OverrideProps } from '../OverridableComponent';
+import { Theme } from '..';
export interface CardHeaderTypeMap<
Props = {},
@@ -54,6 +56,10 @@ export interface CardHeaderTypeMap<
SubheaderTypographyComponent,
{ component?: SubheaderTypographyComponent }
>;
+ /**
+ * The system prop that allows defining system overrides as well as additional CSS styles.
+ */
+ sx?: SxProps;
/**
* The content of the component.
*/
diff --git a/packages/material-ui/src/CardHeader/CardHeader.js b/packages/material-ui/src/CardHeader/CardHeader.js
index f052113ba8e9d9..0f798a0e1a1f17 100644
--- a/packages/material-ui/src/CardHeader/CardHeader.js
+++ b/packages/material-ui/src/CardHeader/CardHeader.js
@@ -1,47 +1,102 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
-import withStyles from '../styles/withStyles';
+import { deepmerge } from '@material-ui/utils';
+import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import Typography from '../Typography';
+import useThemeProps from '../styles/useThemeProps';
+import experimentalStyled from '../styles/experimentalStyled';
+import cardHeaderClasses, { getCardHeaderUtilityClass } from './cardHeaderClasses';
-export const styles = {
+const overridesResolver = (props, styles) => {
+ return deepmerge(styles.root || {}, {
+ [`& .${cardHeaderClasses.avatar}`]: styles.avatar,
+ [`& .${cardHeaderClasses.action}`]: styles.action,
+ [`& .${cardHeaderClasses.content}`]: styles.content,
+ [`& .${cardHeaderClasses.title}`]: styles.title,
+ [`& .${cardHeaderClasses.subheader}`]: styles.subheader,
+ });
+};
+
+const useUtilityClasses = (styleProps) => {
+ const { classes } = styleProps;
+
+ const slots = {
+ root: ['root'],
+ avatar: ['avatar'],
+ action: ['action'],
+ content: ['content'],
+ title: ['title'],
+ subheader: ['subheader'],
+ };
+
+ return composeClasses(slots, getCardHeaderUtilityClass, classes);
+};
+
+const CardHeaderRoot = experimentalStyled(
+ 'div',
+ {},
+ {
+ name: 'MuiCardHeader',
+ slot: 'Root',
+ overridesResolver,
+ },
+)({
/* Styles applied to the root element. */
- root: {
- display: 'flex',
- alignItems: 'center',
- padding: 16,
+ display: 'flex',
+ alignItems: 'center',
+ padding: 16,
+});
+
+const CardHeaderAvatar = experimentalStyled(
+ 'div',
+ {},
+ {
+ name: 'MuiCardHeader',
+ slot: 'Avatar',
},
+)({
/* Styles applied to the avatar element. */
- avatar: {
- display: 'flex',
- flex: '0 0 auto',
- marginRight: 16,
+ display: 'flex',
+ flex: '0 0 auto',
+ marginRight: 16,
+});
+
+const CardHeaderAction = experimentalStyled(
+ 'div',
+ {},
+ {
+ name: 'MuiCardHeader',
+ slot: 'Action',
},
+)({
/* Styles applied to the action element. */
- action: {
- flex: '0 0 auto',
- alignSelf: 'flex-start',
- marginTop: -4,
- marginRight: -8,
- marginBottom: -4,
+ flex: '0 0 auto',
+ alignSelf: 'flex-start',
+ marginTop: -4,
+ marginRight: -8,
+ marginBottom: -4,
+});
+
+const CardHeaderContent = experimentalStyled(
+ 'div',
+ {},
+ {
+ name: 'MuiCardHeader',
+ slot: 'Content',
},
+)({
/* Styles applied to the content wrapper element. */
- content: {
- flex: '1 1 auto',
- },
- /* Styles applied to the title Typography element. */
- title: {},
- /* Styles applied to the subheader Typography element. */
- subheader: {},
-};
+ flex: '1 1 auto',
+});
-const CardHeader = React.forwardRef(function CardHeader(props, ref) {
+const CardHeader = React.forwardRef(function CardHeader(inProps, ref) {
+ const props = useThemeProps({ props: inProps, name: 'MuiCardHeader' });
const {
action,
avatar,
- classes,
className,
- component: Component = 'div',
+ component = 'div',
disableTypography = false,
subheader: subheaderProp,
subheaderTypographyProps,
@@ -50,6 +105,14 @@ const CardHeader = React.forwardRef(function CardHeader(props, ref) {
...other
} = props;
+ const styleProps = {
+ ...props,
+ component,
+ disableTypography,
+ };
+
+ const classes = useUtilityClasses(styleProps);
+
let title = titleProp;
if (title != null && title.type !== Typography && !disableTypography) {
title = (
@@ -82,14 +145,29 @@ const CardHeader = React.forwardRef(function CardHeader(props, ref) {
}
return (
-
- {avatar && {avatar}
}
-
+
+ {avatar && (
+
+ {avatar}
+
+ )}
+
+
{title}
{subheader}
-
- {action && {action}
}
-
+
+ {action && (
+
+ {action}
+
+ )}
+
);
});
@@ -140,6 +218,10 @@ CardHeader.propTypes = {
* (as long as disableTypography is not `true`).
*/
subheaderTypographyProps: PropTypes.object,
+ /**
+ * The system prop that allows defining system overrides as well as additional CSS styles.
+ */
+ sx: PropTypes.object,
/**
* The content of the component.
*/
@@ -151,4 +233,4 @@ CardHeader.propTypes = {
titleTypographyProps: PropTypes.object,
};
-export default withStyles(styles, { name: 'MuiCardHeader' })(CardHeader);
+export default CardHeader;
diff --git a/packages/material-ui/src/CardHeader/CardHeader.test.js b/packages/material-ui/src/CardHeader/CardHeader.test.js
index 8ed3b31bdbdb31..0a097c73787710 100644
--- a/packages/material-ui/src/CardHeader/CardHeader.test.js
+++ b/packages/material-ui/src/CardHeader/CardHeader.test.js
@@ -1,24 +1,24 @@
import * as React from 'react';
import { expect } from 'chai';
-import { getClasses, createMount, createClientRender, describeConformance } from 'test/utils';
+import { createMount, createClientRender, describeConformanceV5 } from 'test/utils';
import CardHeader from './CardHeader';
import { typographyClasses } from '../Typography';
+import classes from './cardHeaderClasses';
describe('', () => {
const mount = createMount();
- let classes;
const render = createClientRender();
- before(() => {
- classes = getClasses();
- });
-
- describeConformance(, () => ({
+ describeConformanceV5(, () => ({
classes,
inheritComponent: 'div',
mount,
+ muiName: 'MuiCardHeader',
refInstanceof: window.HTMLDivElement,
+ testDeepOverrides: { slotName: 'content', slotClassName: classes.content },
testComponentPropWith: 'span',
+ testVariantProps: { variant: 'foo' },
+ skip: ['componentsProp'],
}));
describe('without an avatar', () => {
diff --git a/packages/material-ui/src/CardHeader/cardHeaderClasses.d.ts b/packages/material-ui/src/CardHeader/cardHeaderClasses.d.ts
new file mode 100644
index 00000000000000..0961c645ed6e54
--- /dev/null
+++ b/packages/material-ui/src/CardHeader/cardHeaderClasses.d.ts
@@ -0,0 +1,14 @@
+export interface CardHeaderClasses {
+ root: string;
+ avatar: string;
+ action: string;
+ content: string;
+ title: string;
+ subheader: string;
+}
+
+declare const cardHeaderClasses: CardHeaderClasses;
+
+export function getCardHeaderUtilityClass(slot: string): string;
+
+export default cardHeaderClasses;
diff --git a/packages/material-ui/src/CardHeader/cardHeaderClasses.js b/packages/material-ui/src/CardHeader/cardHeaderClasses.js
new file mode 100644
index 00000000000000..3396d8dac56083
--- /dev/null
+++ b/packages/material-ui/src/CardHeader/cardHeaderClasses.js
@@ -0,0 +1,16 @@
+import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled';
+
+export function getCardHeaderUtilityClass(slot) {
+ return generateUtilityClass('MuiCardHeader', slot);
+}
+
+const cardHeaderClasses = generateUtilityClasses('MuiCardHeader', [
+ 'root',
+ 'avatar',
+ 'action',
+ 'content',
+ 'title',
+ 'subheader',
+]);
+
+export default cardHeaderClasses;
diff --git a/packages/material-ui/src/CardHeader/index.d.ts b/packages/material-ui/src/CardHeader/index.d.ts
index d989494e94ab60..c599bc0c40ab71 100644
--- a/packages/material-ui/src/CardHeader/index.d.ts
+++ b/packages/material-ui/src/CardHeader/index.d.ts
@@ -1,2 +1,5 @@
export { default } from './CardHeader';
export * from './CardHeader';
+
+export { default as cardHeaderClasses } from './cardHeaderClasses';
+export * from './cardHeaderClasses';
diff --git a/packages/material-ui/src/CardHeader/index.js b/packages/material-ui/src/CardHeader/index.js
index 9879cb20030b62..7f66c751b27942 100644
--- a/packages/material-ui/src/CardHeader/index.js
+++ b/packages/material-ui/src/CardHeader/index.js
@@ -1 +1,4 @@
export { default } from './CardHeader';
+
+export { default as cardHeaderClasses } from './cardHeaderClasses';
+export * from './cardHeaderClasses';