Skip to content

Commit

Permalink
[List] Migrate ListSubheader to emotion (mui#24561)
Browse files Browse the repository at this point in the history
  • Loading branch information
queengooborg authored Jan 25, 2021
1 parent 27bbb5b commit 841e805
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 50 deletions.
5 changes: 3 additions & 2 deletions docs/pages/api-docs/list-subheader.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"component": { "type": { "name": "elementType" } },
"disableGutters": { "type": { "name": "bool" } },
"disableSticky": { "type": { "name": "bool" } },
"inset": { "type": { "name": "bool" } }
"inset": { "type": { "name": "bool" } },
"sx": { "type": { "name": "object" } }
},
"name": "ListSubheader",
"styles": {
Expand All @@ -25,6 +26,6 @@
"filename": "/packages/material-ui/src/ListSubheader/ListSubheader.js",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/lists/\">Lists</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"component": "The component used for the root node. Either a string to use a HTML element or a component.",
"disableGutters": "If <code>true</code>, the List Subheader will not have gutters.",
"disableSticky": "If <code>true</code>, the List Subheader will not stick to the top during scroll.",
"inset": "If <code>true</code>, the List Subheader is indented."
"inset": "If <code>true</code>, the List Subheader is indented.",
"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."
},
"classDescriptions": {
"root": { "description": "Styles applied to the root element." },
Expand Down
3 changes: 1 addition & 2 deletions packages/material-ui/src/List/List.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { expect } from 'chai';
import { getClasses, createMount, describeConformance, createClientRender } from 'test/utils';
import ListSubheader from '../ListSubheader';
import ListSubheader, { listSubheaderClasses } from '../ListSubheader';
import List from './List';
import ListItem, { listItemClasses } from '../ListItem';

Expand Down Expand Up @@ -42,7 +42,6 @@ describe('<List />', () => {

it('should render ListSubheader', () => {
const { container } = render(<List subheader={<ListSubheader>Title</ListSubheader>} />);
const listSubheaderClasses = getClasses(<ListSubheader />);
const item = container.querySelector('li');

expect(item).to.have.class(listSubheaderClasses.root);
Expand Down
6 changes: 6 additions & 0 deletions packages/material-ui/src/ListSubheader/ListSubheader.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import * as React from 'react';
import { SxProps } from '@material-ui/system';
import { Theme } from '..';
import { OverridableComponent, OverrideProps } from '../OverridableComponent';

export interface ListSubheaderTypeMap<P = {}, D extends React.ElementType = 'li'> {
Expand Down Expand Up @@ -44,6 +46,10 @@ export interface ListSubheaderTypeMap<P = {}, D extends React.ElementType = 'li'
* @default false
*/
inset?: boolean;
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
};
defaultComponent: D;
}
Expand Down
121 changes: 83 additions & 38 deletions packages/material-ui/src/ListSubheader/ListSubheader.js
Original file line number Diff line number Diff line change
@@ -1,71 +1,112 @@
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 experimentalStyled from '../styles/experimentalStyled';
import useThemeProps from '../styles/useThemeProps';
import capitalize from '../utils/capitalize';
import { getListSubheaderUtilityClass } from './listSubheaderClasses';

export const styles = (theme) => ({
/* Styles applied to the root element. */
root: {
boxSizing: 'border-box',
lineHeight: '48px',
listStyle: 'none',
color: theme.palette.text.secondary,
fontFamily: theme.typography.fontFamily,
fontWeight: theme.typography.fontWeightMedium,
fontSize: theme.typography.pxToRem(14),
const overridesResolver = (props, styles) => {
const { styleProps } = props;

return deepmerge(styles.root || {}, {
...(styleProps.color !== 'default' && styles[`color${capitalize(styleProps.color)}`]),
...(!styleProps.disableGutters && styles.gutters),
...(styleProps.inset && styles.inset),
...(!styleProps.disableSticky && styles.sticky),
});
};

const useUtilityClasses = (styleProps) => {
const { classes, color, disableGutters, inset, disableSticky } = styleProps;

const slots = {
root: [
'root',
color !== 'default' && `color${capitalize(color)}`,
!disableGutters && 'gutters',
inset && 'inset',
!disableSticky && 'sticky',
],
};

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

const ListSubheaderRoot = experimentalStyled(
'li',
{},
{
name: 'MuiListSubheader',
slot: 'Root',
overridesResolver,
},
)(({ theme, styleProps }) => ({
/* Styles applied to the root element. */
boxSizing: 'border-box',
lineHeight: '48px',
listStyle: 'none',
color: theme.palette.text.secondary,
fontFamily: theme.typography.fontFamily,
fontWeight: theme.typography.fontWeightMedium,
fontSize: theme.typography.pxToRem(14),
/* Styles applied to the root element if `color="primary"`. */
colorPrimary: {
...(styleProps.color === 'primary' && {
color: theme.palette.primary.main,
},
}),
/* Styles applied to the root element if `color="inherit"`. */
colorInherit: {
...(styleProps.color === 'inherit' && {
color: 'inherit',
},
/* Styles applied to the inner `component` element unless `disableGutters={true}`. */
gutters: {
}),
/* Styles applied to the root element unless `disableGutters={true}`. */
...(!styleProps.disableGutters && {
paddingLeft: 16,
paddingRight: 16,
},
}),
/* Styles applied to the root element if `inset={true}`. */
inset: {
...(styleProps.inset && {
paddingLeft: 72,
},
}),
/* Styles applied to the root element unless `disableSticky={true}`. */
sticky: {
...(!styleProps.disableSticky && {
position: 'sticky',
top: 0,
zIndex: 1,
backgroundColor: 'inherit',
},
});
}),
}));

const ListSubheader = React.forwardRef(function ListSubheader(props, ref) {
const ListSubheader = React.forwardRef(function ListSubheader(inProps, ref) {
const props = useThemeProps({ props: inProps, name: 'MuiListSubheader' });
const {
classes,
className,
color = 'default',
component: Component = 'li',
component = 'li',
disableGutters = false,
disableSticky = false,
inset = false,
...other
} = props;

const styleProps = {
...props,
color,
component,
disableGutters,
disableSticky,
inset,
};

const classes = useUtilityClasses(styleProps);

return (
<Component
className={clsx(
classes.root,
{
[classes[`color${capitalize(color)}`]]: color !== 'default',
[classes.inset]: inset,
[classes.sticky]: !disableSticky,
[classes.gutters]: !disableGutters,
},
className,
)}
<ListSubheaderRoot
as={component}
className={clsx(classes.root, className)}
ref={ref}
styleProps={styleProps}
{...other}
/>
);
Expand Down Expand Up @@ -113,6 +154,10 @@ ListSubheader.propTypes = {
* @default false
*/
inset: PropTypes.bool,
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiListSubheader' })(ListSubheader);
export default ListSubheader;
13 changes: 6 additions & 7 deletions packages/material-ui/src/ListSubheader/ListSubheader.test.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import * as React from 'react';
import { expect } from 'chai';
import { getClasses, createMount, describeConformance, createClientRender } from 'test/utils';
import { createMount, describeConformanceV5, createClientRender } from 'test/utils';
import ListSubheader from './ListSubheader';
import classes from './listSubheaderClasses';

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

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

describeConformance(<ListSubheader />, () => ({
describeConformanceV5(<ListSubheader />, () => ({
classes,
inheritComponent: 'li',
mount,
muiName: 'MuiListSubheader',
refInstanceof: window.HTMLLIElement,
testVariantProps: { disableGutters: true },
skip: ['componentsProp'],
}));

it('should display primary color', () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/material-ui/src/ListSubheader/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export { default } from './ListSubheader';
export * from './ListSubheader';

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

export { default as listSubheaderClasses } from './listSubheaderClasses';
export * from './listSubheaderClasses';
14 changes: 14 additions & 0 deletions packages/material-ui/src/ListSubheader/listSubheaderClasses.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export interface ListSubheaderClasses {
root: string;
colorPrimary: string;
colorInherit: string;
gutters: string;
inset: string;
sticky: string;
}

declare const listSubheaderClasses: ListSubheaderClasses;

export function getListSubheaderUtilityClass(slot: string): string;

export default listSubheaderClasses;
16 changes: 16 additions & 0 deletions packages/material-ui/src/ListSubheader/listSubheaderClasses.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled';

export function getListSubheaderUtilityClass(slot) {
return generateUtilityClass('MuiListSubheader', slot);
}

const listSubheaderClasses = generateUtilityClasses('MuiListSubheader', [
'root',
'colorPrimary',
'colorInherit',
'gutters',
'inset',
'sticky',
]);

export default listSubheaderClasses;

0 comments on commit 841e805

Please sign in to comment.