Skip to content

Commit

Permalink
[ImageList] Migrate ImageListItemBar to emotion (mui#24632)
Browse files Browse the repository at this point in the history
  • Loading branch information
kodai3 authored and natac13 committed Jan 30, 2021
1 parent 57486e0 commit 1482605
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 87 deletions.
3 changes: 2 additions & 1 deletion docs/pages/api-docs/image-list-item-bar.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"default": "'bottom'"
},
"subtitle": { "type": { "name": "node" } },
"sx": { "type": { "name": "object" } },
"title": { "type": { "name": "node" } }
},
"name": "ImageListItemBar",
Expand All @@ -40,6 +41,6 @@
"filename": "/packages/material-ui/src/ImageListItemBar/ImageListItemBar.js",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/image-list/\">Image List</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"classes": "Override or extend the styles applied to the component. See <a href=\"#css\">CSS API</a> below for more details.",
"position": "Position of the title bar.",
"subtitle": "String or element serving as subtitle (support text).",
"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": "Title to be displayed."
},
"classDescriptions": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SxProps } from '@material-ui/system';
import * as React from 'react';
import { InternalStandardProps as StandardProps } from '..';
import { InternalStandardProps as StandardProps, Theme } from '..';

export interface ImageListItemBarProps
extends StandardProps<React.HTMLAttributes<HTMLDivElement>, 'title'> {
Expand Down Expand Up @@ -51,6 +52,10 @@ export interface ImageListItemBarProps
* String or element serving as subtitle (support text).
*/
subtitle?: React.ReactNode;
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
/**
* Title to be displayed.
*/
Expand Down
244 changes: 168 additions & 76 deletions packages/material-ui/src/ImageListItemBar/ImageListItemBar.js
Original file line number Diff line number Diff line change
@@ -1,125 +1,213 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import { deepmerge } from '@material-ui/utils';
import clsx from 'clsx';
import withStyles from '../styles/withStyles';
import PropTypes from 'prop-types';
import * as React from 'react';
import experimentalStyled from '../styles/experimentalStyled';
import useThemeProps from '../styles/useThemeProps';
import capitalize from '../utils/capitalize';
import imageListItemBarClasses, {
getImageListItemBarUtilityClass,
} from './imageListItemBarClasses';

const overridesResolver = (props, styles) => {
const { styleProps } = props;

return deepmerge(styles.root || {}, {
...styles[`position${capitalize(styleProps.position)}`],
[`& .${imageListItemBarClasses.titleWrap}`]: {
...styles.titleWrap,
...styles[`titleWrap${capitalize(styleProps.position)}`],
...(styleProps.actionIcon &&
styles[`titleWrapActionPos${capitalize(styleProps.actionPosition)}`]),
},
[`& .${imageListItemBarClasses.title}`]: styles.title,
[`& .${imageListItemBarClasses.subtitle}`]: styles.subtitle,
[`& .${imageListItemBarClasses.actionIcon}`]: {
...styles.actionIcon,
...styles[`actionIconActionPos${capitalize(styleProps.actionPosition)}`],
},
});
};

const useUtilityClasses = (styleProps) => {
const { classes, position, actionIcon, actionPosition } = styleProps;

export const styles = (theme) => ({
/* Styles applied to the root element. */
root: {
const slots = {
root: ['root', `position${capitalize(position)}`],
titleWrap: [
'titleWrap',
`titleWrap${capitalize(position)}`,
actionIcon && `titleWrapActionPos${capitalize(actionPosition)}`,
],
title: ['title'],
subtitle: ['subtitle'],
actionIcon: ['actionIcon', `actionIconActionPos${capitalize(actionPosition)}`],
};

return composeClasses(slots, getImageListItemBarUtilityClass, classes);
};

const ImageListItemBarRoot = experimentalStyled(
'div',
{},
{
name: 'MuiImageListItemBar',
slot: 'Root',
overridesResolver,
},
)(({ theme, styleProps }) => {
return {
/* Styles applied to the root element. */
position: 'absolute',
left: 0,
right: 0,
background: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
alignItems: 'center',
fontFamily: theme.typography.fontFamily,
/* Styles applied to the root element if `position="bottom"`. */
...(styleProps.position === 'bottom' && {
bottom: 0,
}),
/* Styles applied to the root element if `position="top"`. */
...(styleProps.position === 'top' && {
top: 0,
}),
/* Styles applied to the root element if `position="below"`. */
...(styleProps.position === 'below' && {
position: 'relative',
background: 'transparent',
alignItems: 'normal',
}),
};
});

const ImageListItemBarTitleWrap = experimentalStyled(
'div',
{},
{
name: 'MuiImageListItemBar',
slot: 'TitleWrap',
},
/* Styles applied to the root element if `position="bottom"`. */
positionBottom: {
bottom: 0,
},
/* Styles applied to the root element if `position="top"`. */
positionTop: {
top: 0,
},
/* Styles applied to the root element if `position="below"`. */
positionBelow: {
position: 'relative',
background: 'transparent',
alignItems: 'normal',
},
/* Styles applied to the title and subtitle container element. */
titleWrap: {
)(({ theme, styleProps }) => {
return {
/* Styles applied to the title and subtitle container element. */
flexGrow: 1,
padding: '12px 16px',
color: theme.palette.common.white,
overflow: 'hidden',
/* Styles applied to the title and subtitle container element if `position="below"`. */
...(styleProps.position === 'below' && {
padding: '6px 0 12px',
color: 'inherit',
}),
/* Styles applied to the container element if `actionPosition="left"`. */
...(styleProps.actionIcon &&
styleProps.actionPosition === 'left' && {
paddingLeft: 0,
}),
/* Styles applied to the container element if `actionPosition="right"`. */
...(styleProps.actionIcon &&
styleProps.actionPosition === 'right' && {
paddingRight: 0,
}),
};
});

const ImageListItemBarTitle = experimentalStyled(
'div',
{},
{
name: 'MuiImageListItemBar',
slot: 'Title',
},
/* Styles applied to the title and subtitle container element if `position="below"`. */
titleWrapBelow: {
padding: '6px 0 12px',
color: 'inherit',
},
/* Styles applied to the container element if `actionPosition="left"`. */
titleWrapActionPosLeft: {
paddingLeft: 0,
},
/* Styles applied to the container element if `actionPosition="right"`. */
titleWrapActionPosRight: {
paddingRight: 0,
},
/* Styles applied to the title container element. */
title: {
)(({ theme }) => {
return {
/* Styles applied to the title container element. */
fontSize: theme.typography.pxToRem(16),
lineHeight: '24px',
textOverflow: 'ellipsis',
overflow: 'hidden',
whiteSpace: 'nowrap',
};
});

const ImageListItemBarSubtitle = experimentalStyled(
'div',
{},
{
name: 'MuiImageListItemBar',
slot: 'Subtitle',
},
/* Styles applied to the subtitle container element. */
subtitle: {
)(({ theme }) => {
return {
/* Styles applied to the subtitle container element. */
fontSize: theme.typography.pxToRem(12),
lineHeight: 1,
textOverflow: 'ellipsis',
overflow: 'hidden',
whiteSpace: 'nowrap',
};
});

const ImageListItemBarActionIcon = experimentalStyled(
'div',
{},
{
name: 'MuiImageListItemBar',
slot: 'ActionIcon',
},
/* Styles applied to the actionIcon if supplied. */
actionIcon: {},
/* Styles applied to the actionIcon if `actionPosition="left"`. */
actionIconActionPosLeft: {
order: -1,
},
)(({ styleProps }) => {
return {
/* Styles applied to the actionIcon if `actionPosition="left"`. */
...(styleProps.actionPosition === 'left' && {
order: -1,
}),
};
});

const ImageListItemBar = React.forwardRef(function ImageListItemBar(props, ref) {
const ImageListItemBar = React.forwardRef(function ImageListItemBar(inProps, ref) {
const props = useThemeProps({
props: inProps,
name: 'MuiImageListItemBar',
});

const {
actionIcon,
actionPosition = 'right',
classes,
className,
subtitle,
title,
position = 'bottom',
...other
} = props;

const actionPos = actionIcon && actionPosition;
const styleProps = { ...props, position, actionPosition };

const classes = useUtilityClasses(styleProps);

return (
<div
className={clsx(
classes.root,
{
[classes.positionBelow]: position === 'below',
[classes.positionBottom]: position === 'bottom',
[classes.positionTop]: position === 'top',
},
className,
)}
<ImageListItemBarRoot
styleProps={styleProps}
className={clsx(classes.root, className)}
ref={ref}
{...other}
>
<div
className={clsx(classes.titleWrap, {
[classes.titleWrapBelow]: position === 'below',
[classes.titleWrapActionPosLeft]: actionPos === 'left',
[classes.titleWrapActionPosRight]: actionPos === 'right',
})}
>
<div className={classes.title}>{title}</div>
{subtitle ? <div className={classes.subtitle}>{subtitle}</div> : null}
</div>
<ImageListItemBarTitleWrap styleProps={styleProps} className={classes.titleWrap}>
<ImageListItemBarTitle className={classes.title}>{title}</ImageListItemBarTitle>
{subtitle ? (
<ImageListItemBarSubtitle className={classes.subtitle}>
{subtitle}
</ImageListItemBarSubtitle>
) : null}
</ImageListItemBarTitleWrap>
{actionIcon ? (
<div
className={clsx(classes.actionIcon, {
[classes.actionIconActionPosLeft]: actionPos === 'left',
})}
>
<ImageListItemBarActionIcon styleProps={styleProps} className={classes.actionIcon}>
{actionIcon}
</div>
</ImageListItemBarActionIcon>
) : null}
</div>
</ImageListItemBarRoot>
);
});

Expand Down Expand Up @@ -159,10 +247,14 @@ ImageListItemBar.propTypes = {
* String or element serving as subtitle (support text).
*/
subtitle: PropTypes.node,
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.object,
/**
* Title to be displayed.
*/
title: PropTypes.node,
};

export default withStyles(styles, { name: 'MuiImageListItemBar' })(ImageListItemBar);
export default ImageListItemBar;
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import * as React from 'react';
import { expect } from 'chai';
import { createClientRender, getClasses, createMount, describeConformance } from 'test/utils';
import * as React from 'react';
import { createClientRender, createMount, describeConformanceV5 } from 'test/utils';
import ImageListItemBar from './ImageListItemBar';
import classes from './imageListItemBarClasses';

describe('<ImageListItemBar />', () => {
let classes;
const mount = createMount();
const render = createClientRender();

before(() => {
classes = getClasses(<ImageListItemBar title="classes" />);
});

describeConformance(<ImageListItemBar title="conform?" />, () => ({
describeConformanceV5(<ImageListItemBar title="conform?" />, () => ({
classes,
inheritComponent: 'div',
mount,
refInstanceof: window.HTMLDivElement,
skip: ['componentProp'],
muiName: 'MuiImageListItemBar',
testDeepOverrides: { slotName: 'titleWrap', slotClassName: classes.titleWrap },
testVariantProps: { position: 'top', actionPosition: 'left' },
skip: ['componentProp', 'componentsProp'],
}));

const itemData = {
Expand Down
Loading

0 comments on commit 1482605

Please sign in to comment.