Skip to content

Commit

Permalink
[Card] Migrate CardHeader to emotion (#24626)
Browse files Browse the repository at this point in the history
  • Loading branch information
natac13 committed Jan 27, 2021
1 parent 74dcb12 commit ca2960e
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 42 deletions.
3 changes: 2 additions & 1 deletion docs/pages/api-docs/card-header.json
Original file line number Diff line number Diff line change
Expand Up @@ -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" } }
},
Expand All @@ -21,6 +22,6 @@
"filename": "/packages/material-ui/src/CardHeader/CardHeader.js",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/cards/\">Cards</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
1 change: 1 addition & 0 deletions docs/translations/api-docs/card-header/card-header.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"disableTypography": "If <code>true</code>, <code>subheader</code> and <code>title</code> won&#39;t be wrapped by a Typography component. This can be useful to render an alternative Typography variant by wrapping the <code>title</code> text, and optional <code>subheader</code> 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 <code>true</code>).",
"sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the <a href=\"/system/basics/#the-sx-prop\">`sx` page</a> for more details.",
"title": "The content of the component.",
"titleTypographyProps": "These props will be forwarded to the title (as long as disableTypography is not <code>true</code>)."
},
Expand Down
6 changes: 6 additions & 0 deletions packages/material-ui/src/CardHeader/CardHeader.d.ts
Original file line number Diff line number Diff line change
@@ -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 = {},
Expand Down Expand Up @@ -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<Theme>;
/**
* The content of the component.
*/
Expand Down
150 changes: 116 additions & 34 deletions packages/material-ui/src/CardHeader/CardHeader.js
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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 = (
Expand Down Expand Up @@ -82,14 +145,29 @@ const CardHeader = React.forwardRef(function CardHeader(props, ref) {
}

return (
<Component className={clsx(classes.root, className)} ref={ref} {...other}>
{avatar && <div className={classes.avatar}>{avatar}</div>}
<div className={classes.content}>
<CardHeaderRoot
className={clsx(classes.root, className)}
as={component}
ref={ref}
styleProps={styleProps}
{...other}
>
{avatar && (
<CardHeaderAvatar className={classes.avatar} styleProps={styleProps}>
{avatar}
</CardHeaderAvatar>
)}

<CardHeaderContent className={classes.content} styleProps={styleProps}>
{title}
{subheader}
</div>
{action && <div className={classes.action}>{action}</div>}
</Component>
</CardHeaderContent>
{action && (
<CardHeaderAction className={classes.action} styleProps={styleProps}>
{action}
</CardHeaderAction>
)}
</CardHeaderRoot>
);
});

Expand Down Expand Up @@ -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.
*/
Expand All @@ -151,4 +233,4 @@ CardHeader.propTypes = {
titleTypographyProps: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiCardHeader' })(CardHeader);
export default CardHeader;
14 changes: 7 additions & 7 deletions packages/material-ui/src/CardHeader/CardHeader.test.js
Original file line number Diff line number Diff line change
@@ -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('<CardHeader />', () => {
const mount = createMount();
let classes;
const render = createClientRender();

before(() => {
classes = getClasses(<CardHeader />);
});

describeConformance(<CardHeader />, () => ({
describeConformanceV5(<CardHeader />, () => ({
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', () => {
Expand Down
14 changes: 14 additions & 0 deletions packages/material-ui/src/CardHeader/cardHeaderClasses.d.ts
Original file line number Diff line number Diff line change
@@ -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;
16 changes: 16 additions & 0 deletions packages/material-ui/src/CardHeader/cardHeaderClasses.js
Original file line number Diff line number Diff line change
@@ -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;
3 changes: 3 additions & 0 deletions packages/material-ui/src/CardHeader/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export { default } from './CardHeader';
export * from './CardHeader';

export { default as cardHeaderClasses } from './cardHeaderClasses';
export * from './cardHeaderClasses';
3 changes: 3 additions & 0 deletions packages/material-ui/src/CardHeader/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export { default } from './CardHeader';

export { default as cardHeaderClasses } from './cardHeaderClasses';
export * from './cardHeaderClasses';

0 comments on commit ca2960e

Please sign in to comment.