diff --git a/docs/pages/api-docs/list-item-avatar.json b/docs/pages/api-docs/list-item-avatar.json index 1f11c2b48a93b0..d743d919811cd3 100644 --- a/docs/pages/api-docs/list-item-avatar.json +++ b/docs/pages/api-docs/list-item-avatar.json @@ -1,7 +1,8 @@ { "props": { "children": { "type": { "name": "node" } }, - "classes": { "type": { "name": "object" } } + "classes": { "type": { "name": "object" } }, + "sx": { "type": { "name": "object" } } }, "name": "ListItemAvatar", "styles": { @@ -14,6 +15,6 @@ "filename": "/packages/material-ui/src/ListItemAvatar/ListItemAvatar.js", "inheritance": null, "demos": "", - "styledComponent": false, + "styledComponent": true, "cssComponent": false } diff --git a/docs/translations/api-docs/list-item-avatar/list-item-avatar.json b/docs/translations/api-docs/list-item-avatar/list-item-avatar.json index 307eb5697ddff3..3e647405ead18a 100644 --- a/docs/translations/api-docs/list-item-avatar/list-item-avatar.json +++ b/docs/translations/api-docs/list-item-avatar/list-item-avatar.json @@ -2,7 +2,8 @@ "componentDescription": "A simple wrapper to apply `List` styles to an `Avatar`.", "propDescriptions": { "children": "The content of the component, normally an Avatar.", - "classes": "Override or extend the styles applied to the component. See CSS API below for more details." + "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." }, "classDescriptions": { "root": { "description": "Styles applied to the root element." }, diff --git a/packages/material-ui/src/ListItemAvatar/ListItemAvatar.d.ts b/packages/material-ui/src/ListItemAvatar/ListItemAvatar.d.ts index b633a66227e316..610c7a9d274f17 100644 --- a/packages/material-ui/src/ListItemAvatar/ListItemAvatar.d.ts +++ b/packages/material-ui/src/ListItemAvatar/ListItemAvatar.d.ts @@ -1,4 +1,5 @@ -import { InternalStandardProps as StandardProps } from '..'; +import { SxProps } from '@material-ui/system'; +import { InternalStandardProps as StandardProps, Theme } from '..'; export interface ListItemAvatarProps extends StandardProps> { /** @@ -14,6 +15,10 @@ export interface ListItemAvatarProps extends StandardProps; } export type ListItemAvatarClassKey = keyof NonNullable; diff --git a/packages/material-ui/src/ListItemAvatar/ListItemAvatar.js b/packages/material-ui/src/ListItemAvatar/ListItemAvatar.js index 0ce85bc5ea7334..11481456b8df7c 100644 --- a/packages/material-ui/src/ListItemAvatar/ListItemAvatar.js +++ b/packages/material-ui/src/ListItemAvatar/ListItemAvatar.js @@ -1,37 +1,67 @@ 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 ListContext from '../List/ListContext'; +import experimentalStyled from '../styles/experimentalStyled'; +import useThemeProps from '../styles/useThemeProps'; +import { getListItemAvatarUtilityClass } from './listItemAvatarClasses'; -export const styles = { - /* Styles applied to the root element. */ - root: { - minWidth: 56, - flexShrink: 0, +const overridesResolver = (props, styles) => { + const { styleProps } = props; + + return deepmerge(styles.root || {}, { + ...(styleProps.alignItems === 'flex-start' && styles.alignItemsFlexStart), + }); +}; + +const useUtilityClasses = (styleProps) => { + const { alignItems, classes } = styleProps; + + const slots = { + root: ['root', alignItems === 'flex-start' && 'alignItemsFlexStart'], + }; + + return composeClasses(slots, getListItemAvatarUtilityClass, classes); +}; + +const ListItemAvatarRoot = experimentalStyled( + 'div', + {}, + { + name: 'MuiListItemAvatar', + slot: 'Root', + overridesResolver, }, +)(({ styleProps }) => ({ + /* Styles applied to the root element. */ + minWidth: 56, + flexShrink: 0, /* Styles applied to the root element when the parent `ListItem` uses `alignItems="flex-start"`. */ - alignItemsFlexStart: { + ...(styleProps.alignItems === 'flex-start' && { marginTop: 8, - }, -}; + }), +})); /** * A simple wrapper to apply `List` styles to an `Avatar`. */ -const ListItemAvatar = React.forwardRef(function ListItemAvatar(props, ref) { - const { classes, className, ...other } = props; +const ListItemAvatar = React.forwardRef(function ListItemAvatar(inProps, ref) { + const props = useThemeProps({ + props: inProps, + name: 'MuiListItemAvatar', + }); + + const { className, ...other } = props; const context = React.useContext(ListContext); + const styleProps = { ...props, alignItems: context.alignItems }; + const classes = useUtilityClasses(styleProps); return ( -
@@ -55,6 +85,10 @@ ListItemAvatar.propTypes = { * @ignore */ className: PropTypes.string, + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx: PropTypes.object, }; -export default withStyles(styles, { name: 'MuiListItemAvatar' })(ListItemAvatar); +export default ListItemAvatar; diff --git a/packages/material-ui/src/ListItemAvatar/ListItemAvatar.test.js b/packages/material-ui/src/ListItemAvatar/ListItemAvatar.test.js index 73161cd5d0e69e..c072e7c5f4e185 100644 --- a/packages/material-ui/src/ListItemAvatar/ListItemAvatar.test.js +++ b/packages/material-ui/src/ListItemAvatar/ListItemAvatar.test.js @@ -1,20 +1,12 @@ import * as React from 'react'; -import { getClasses, createMount, describeConformance } from 'test/utils'; +import { createMount, describeConformanceV5 } from 'test/utils'; import ListItemAvatar from './ListItemAvatar'; +import classes from './listItemAvatarClasses'; describe('', () => { const mount = createMount(); - let classes; - before(() => { - classes = getClasses( - -
- , - ); - }); - - describeConformance( + describeConformanceV5(
, @@ -22,8 +14,9 @@ describe('', () => { classes, inheritComponent: 'div', mount, + muiName: 'MuiListItemAvatar', refInstanceof: window.HTMLDivElement, - skip: ['componentProp'], + skip: ['componentProp', 'componentsProp', 'themeVariants'], }), ); }); diff --git a/packages/material-ui/src/ListItemAvatar/index.d.ts b/packages/material-ui/src/ListItemAvatar/index.d.ts index f542f30d134d1f..70accfc1af3b70 100644 --- a/packages/material-ui/src/ListItemAvatar/index.d.ts +++ b/packages/material-ui/src/ListItemAvatar/index.d.ts @@ -1,2 +1,5 @@ export { default } from './ListItemAvatar'; export * from './ListItemAvatar'; + +export { default as listItemAvatarClasses } from './listItemAvatarClasses'; +export * from './listItemAvatarClasses'; diff --git a/packages/material-ui/src/ListItemAvatar/index.js b/packages/material-ui/src/ListItemAvatar/index.js index cc7c625614475b..767e616b6cf072 100644 --- a/packages/material-ui/src/ListItemAvatar/index.js +++ b/packages/material-ui/src/ListItemAvatar/index.js @@ -1 +1,4 @@ export { default } from './ListItemAvatar'; + +export { default as listItemAvatarClasses } from './listItemAvatarClasses'; +export * from './listItemAvatarClasses'; diff --git a/packages/material-ui/src/ListItemAvatar/listItemAvatarClasses.d.ts b/packages/material-ui/src/ListItemAvatar/listItemAvatarClasses.d.ts new file mode 100644 index 00000000000000..377df9904440f6 --- /dev/null +++ b/packages/material-ui/src/ListItemAvatar/listItemAvatarClasses.d.ts @@ -0,0 +1,10 @@ +export interface ListItemAvatarClasses { + root: string; + alignItemsFlexStart: string; +} + +declare const listItemAvatarClasses: ListItemAvatarClasses; + +export function getListItemAvatarUtilityClass(slot: string): string; + +export default listItemAvatarClasses; diff --git a/packages/material-ui/src/ListItemAvatar/listItemAvatarClasses.js b/packages/material-ui/src/ListItemAvatar/listItemAvatarClasses.js new file mode 100644 index 00000000000000..604c17dfdee6d7 --- /dev/null +++ b/packages/material-ui/src/ListItemAvatar/listItemAvatarClasses.js @@ -0,0 +1,12 @@ +import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled'; + +export function getListItemAvatarUtilityClass(slot) { + return generateUtilityClass('MuiListItemAvatar', slot); +} + +const listItemAvatarClasses = generateUtilityClasses('MuiListItemAvatar', [ + 'root', + 'alignItemsFlexStart', +]); + +export default listItemAvatarClasses;