From 841e805c544524e69b8c07a25a6f924cb0031e1b Mon Sep 17 00:00:00 2001 From: Queen Vinyl Darkscratch Date: Sun, 24 Jan 2021 23:42:40 -0800 Subject: [PATCH] [List] Migrate ListSubheader to emotion (#24561) --- docs/pages/api-docs/list-subheader.json | 5 +- .../list-subheader/list-subheader.json | 3 +- packages/material-ui/src/List/List.test.js | 3 +- .../src/ListSubheader/ListSubheader.d.ts | 6 + .../src/ListSubheader/ListSubheader.js | 121 ++++++++++++------ .../src/ListSubheader/ListSubheader.test.js | 13 +- .../material-ui/src/ListSubheader/index.d.ts | 3 + .../material-ui/src/ListSubheader/index.js | 3 + .../ListSubheader/listSubheaderClasses.d.ts | 14 ++ .../src/ListSubheader/listSubheaderClasses.js | 16 +++ 10 files changed, 137 insertions(+), 50 deletions(-) create mode 100644 packages/material-ui/src/ListSubheader/listSubheaderClasses.d.ts create mode 100644 packages/material-ui/src/ListSubheader/listSubheaderClasses.js diff --git a/docs/pages/api-docs/list-subheader.json b/docs/pages/api-docs/list-subheader.json index ee0962199fab10..e6a21e2f31cf64 100644 --- a/docs/pages/api-docs/list-subheader.json +++ b/docs/pages/api-docs/list-subheader.json @@ -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": { @@ -25,6 +26,6 @@ "filename": "/packages/material-ui/src/ListSubheader/ListSubheader.js", "inheritance": null, "demos": "", - "styledComponent": false, + "styledComponent": true, "cssComponent": false } diff --git a/docs/translations/api-docs/list-subheader/list-subheader.json b/docs/translations/api-docs/list-subheader/list-subheader.json index cb169074213da3..96ce291bdb72bd 100644 --- a/docs/translations/api-docs/list-subheader/list-subheader.json +++ b/docs/translations/api-docs/list-subheader/list-subheader.json @@ -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 true, the List Subheader will not have gutters.", "disableSticky": "If true, the List Subheader will not stick to the top during scroll.", - "inset": "If true, the List Subheader is indented." + "inset": "If true, the List Subheader is indented.", + "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/List/List.test.js b/packages/material-ui/src/List/List.test.js index d551f15b7c0ea3..6da9700b54ce04 100644 --- a/packages/material-ui/src/List/List.test.js +++ b/packages/material-ui/src/List/List.test.js @@ -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'; @@ -42,7 +42,6 @@ describe('', () => { it('should render ListSubheader', () => { const { container } = render(Title} />); - const listSubheaderClasses = getClasses(); const item = container.querySelector('li'); expect(item).to.have.class(listSubheaderClasses.root); diff --git a/packages/material-ui/src/ListSubheader/ListSubheader.d.ts b/packages/material-ui/src/ListSubheader/ListSubheader.d.ts index b9c1a813fbe221..7e185f1daabea4 100644 --- a/packages/material-ui/src/ListSubheader/ListSubheader.d.ts +++ b/packages/material-ui/src/ListSubheader/ListSubheader.d.ts @@ -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

{ @@ -44,6 +46,10 @@ export interface ListSubheaderTypeMap

; }; defaultComponent: D; } diff --git a/packages/material-ui/src/ListSubheader/ListSubheader.js b/packages/material-ui/src/ListSubheader/ListSubheader.js index 0c8c94279b9252..385a1e284930ac 100644 --- a/packages/material-ui/src/ListSubheader/ListSubheader.js +++ b/packages/material-ui/src/ListSubheader/ListSubheader.js @@ -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 ( - ); @@ -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; diff --git a/packages/material-ui/src/ListSubheader/ListSubheader.test.js b/packages/material-ui/src/ListSubheader/ListSubheader.test.js index cfc30b43d4c95a..3c09f8725122ee 100644 --- a/packages/material-ui/src/ListSubheader/ListSubheader.test.js +++ b/packages/material-ui/src/ListSubheader/ListSubheader.test.js @@ -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('', () => { const mount = createMount(); const render = createClientRender(); - let classes; - before(() => { - classes = getClasses(); - }); - - describeConformance(, () => ({ + describeConformanceV5(, () => ({ classes, inheritComponent: 'li', mount, + muiName: 'MuiListSubheader', refInstanceof: window.HTMLLIElement, + testVariantProps: { disableGutters: true }, + skip: ['componentsProp'], })); it('should display primary color', () => { diff --git a/packages/material-ui/src/ListSubheader/index.d.ts b/packages/material-ui/src/ListSubheader/index.d.ts index 515934dd43c6db..a38eca969f9cc7 100644 --- a/packages/material-ui/src/ListSubheader/index.d.ts +++ b/packages/material-ui/src/ListSubheader/index.d.ts @@ -1,2 +1,5 @@ export { default } from './ListSubheader'; export * from './ListSubheader'; + +export { default as listSubheaderClasses } from './listSubheaderClasses'; +export * from './listSubheaderClasses'; diff --git a/packages/material-ui/src/ListSubheader/index.js b/packages/material-ui/src/ListSubheader/index.js index c386d6ef8022c4..efc177069c73ee 100644 --- a/packages/material-ui/src/ListSubheader/index.js +++ b/packages/material-ui/src/ListSubheader/index.js @@ -1 +1,4 @@ export { default } from './ListSubheader'; + +export { default as listSubheaderClasses } from './listSubheaderClasses'; +export * from './listSubheaderClasses'; diff --git a/packages/material-ui/src/ListSubheader/listSubheaderClasses.d.ts b/packages/material-ui/src/ListSubheader/listSubheaderClasses.d.ts new file mode 100644 index 00000000000000..c61696b2a6fd3a --- /dev/null +++ b/packages/material-ui/src/ListSubheader/listSubheaderClasses.d.ts @@ -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; diff --git a/packages/material-ui/src/ListSubheader/listSubheaderClasses.js b/packages/material-ui/src/ListSubheader/listSubheaderClasses.js new file mode 100644 index 00000000000000..61f7a8250bc267 --- /dev/null +++ b/packages/material-ui/src/ListSubheader/listSubheaderClasses.js @@ -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;