diff --git a/docs/pages/api-docs/snackbar-content.json b/docs/pages/api-docs/snackbar-content.json index 828dae95f1e393..91ead472f9b81d 100644 --- a/docs/pages/api-docs/snackbar-content.json +++ b/docs/pages/api-docs/snackbar-content.json @@ -3,7 +3,8 @@ "action": { "type": { "name": "node" } }, "classes": { "type": { "name": "object" } }, "message": { "type": { "name": "node" } }, - "role": { "type": { "name": "string" }, "default": "'alert'" } + "role": { "type": { "name": "string" }, "default": "'alert'" }, + "sx": { "type": { "name": "object" } } }, "name": "SnackbarContent", "styles": { @@ -16,6 +17,6 @@ "filename": "/packages/material-ui/src/SnackbarContent/SnackbarContent.js", "inheritance": { "component": "Paper", "pathname": "/api/paper/" }, "demos": "", - "styledComponent": false, + "styledComponent": true, "cssComponent": false } diff --git a/docs/translations/api-docs/snackbar-content/snackbar-content.json b/docs/translations/api-docs/snackbar-content/snackbar-content.json index ed06fd15c166ae..f9063db926c169 100644 --- a/docs/translations/api-docs/snackbar-content/snackbar-content.json +++ b/docs/translations/api-docs/snackbar-content/snackbar-content.json @@ -4,7 +4,8 @@ "action": "The action to display. It renders after the message, at the end of the snackbar.", "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", "message": "The message to display.", - "role": "The ARIA role attribute of the element." + "role": "The ARIA role attribute of the element.", + "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/framer/scripts/framerConfig.js b/framer/scripts/framerConfig.js index ddba979c610c9b..852a8a0136e2cf 100644 --- a/framer/scripts/framerConfig.js +++ b/framer/scripts/framerConfig.js @@ -292,7 +292,7 @@ export const componentSettings = { template: 'slider.txt', }, SnackbarContent: { - ignoredProps: ['action', 'role'], + ignoredProps: ['action', 'role', 'sx'], propValues: { width: 568, height: 48, diff --git a/packages/material-ui/src/AccordionDetails/AccordionDetails.js b/packages/material-ui/src/AccordionDetails/AccordionDetails.js index d345b4ffbe6974..180eb636cb7628 100644 --- a/packages/material-ui/src/AccordionDetails/AccordionDetails.js +++ b/packages/material-ui/src/AccordionDetails/AccordionDetails.js @@ -36,6 +36,7 @@ const AccordionDetailsRoot = experimentalStyled( const AccordionDetails = React.forwardRef(function AccordionDetails(inProps, ref) { const props = useThemeProps({ props: inProps, name: 'MuiAccordionDetails' }); const { className, ...other } = props; + // TODO: convert to simple assignment after the type error in defaultPropsHandler.js:60:6 is fixed const styleProps = { ...props }; const classes = useUtilityClasses(styleProps); diff --git a/packages/material-ui/src/SnackbarContent/SnackbarContent.d.ts b/packages/material-ui/src/SnackbarContent/SnackbarContent.d.ts index 32eb0509a7904e..1ab4c7c092b144 100644 --- a/packages/material-ui/src/SnackbarContent/SnackbarContent.d.ts +++ b/packages/material-ui/src/SnackbarContent/SnackbarContent.d.ts @@ -1,4 +1,6 @@ import * as React from 'react'; +import { SxProps } from '@material-ui/system'; +import { Theme } from '../styles'; import { InternalStandardProps as StandardProps } from '..'; import { PaperProps } from '../Paper'; @@ -27,6 +29,10 @@ export interface SnackbarContentProps extends StandardProps; } export type SnackbarContentClassKey = keyof NonNullable; diff --git a/packages/material-ui/src/SnackbarContent/SnackbarContent.js b/packages/material-ui/src/SnackbarContent/SnackbarContent.js index 94e819d4191bd1..0caa4d76419a9a 100644 --- a/packages/material-ui/src/SnackbarContent/SnackbarContent.js +++ b/packages/material-ui/src/SnackbarContent/SnackbarContent.js @@ -1,61 +1,114 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; -import withStyles from '../styles/withStyles'; -import Paper from '../Paper'; +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 { emphasize } from '../styles/colorManipulator'; +import Paper from '../Paper'; +import snackbarContentClasses, { getSnackbarContentUtilityClass } from './snackbarContentClasses'; + +const overridesResolver = (props, styles) => { + return deepmerge(styles.root || {}, { + [`& .${snackbarContentClasses.action}`]: styles.action, + [`& .${snackbarContentClasses.message}`]: styles.message, + }); +}; + +const useUtilityClasses = (styleProps) => { + const { classes } = styleProps; -export const styles = (theme) => { + const slots = { + root: ['root'], + action: ['action'], + message: ['message'], + }; + + return composeClasses(slots, getSnackbarContentUtilityClass, classes); +}; + +const SnackbarContentRoot = experimentalStyled( + Paper, + {}, + { + name: 'MuiSnackbarContent', + slot: 'Root', + overridesResolver, + }, +)(({ theme }) => { const emphasis = theme.palette.mode === 'light' ? 0.8 : 0.98; const backgroundColor = emphasize(theme.palette.background.default, emphasis); return { - /* Styles applied to the root element. */ - root: { - ...theme.typography.body2, - color: theme.palette.getContrastText(backgroundColor), - backgroundColor, - display: 'flex', - alignItems: 'center', - flexWrap: 'wrap', - padding: '6px 16px', - borderRadius: theme.shape.borderRadius, - flexGrow: 1, - [theme.breakpoints.up('sm')]: { - flexGrow: 'initial', - minWidth: 288, - }, - }, - /* Styles applied to the message wrapper element. */ - message: { - padding: '8px 0', - }, - /* Styles applied to the action wrapper element if `action` is provided. */ - action: { - display: 'flex', - alignItems: 'center', - marginLeft: 'auto', - paddingLeft: 16, - marginRight: -8, + ...theme.typography.body2, + color: theme.palette.getContrastText(backgroundColor), + backgroundColor, + display: 'flex', + alignItems: 'center', + flexWrap: 'wrap', + padding: '6px 16px', + borderRadius: theme.shape.borderRadius, + flexGrow: 1, + [theme.breakpoints.up('sm')]: { + flexGrow: 'initial', + minWidth: 288, }, }; -}; +}); -const SnackbarContent = React.forwardRef(function SnackbarContent(props, ref) { - const { action, classes, className, message, role = 'alert', ...other } = props; +const SnackbarContentMessage = experimentalStyled( + 'div', + {}, + { + name: 'MuiSnackbarContent', + slot: 'Message', + }, +)({ + padding: '8px 0', +}); + +const SnackbarContentAction = experimentalStyled( + 'div', + {}, + { + name: 'MuiSnackbarContent', + slot: 'Action', + }, +)({ + display: 'flex', + alignItems: 'center', + marginLeft: 'auto', + paddingLeft: 16, + marginRight: -8, +}); + +const SnackbarContent = React.forwardRef(function SnackbarContent(inProps, ref) { + const props = useThemeProps({ props: inProps, name: 'MuiSnackbarContent' }); + const { action, className, message, role = 'alert', ...other } = props; + // TODO: convert to simple assignment after the type error in defaultPropsHandler.js:60:6 is fixed + const styleProps = { ...props }; + const classes = useUtilityClasses(styleProps); return ( - -
{message}
- {action ?
{action}
: null} -
+ + {message} + + {action ? ( + + {action} + + ) : null} + ); }); @@ -85,6 +138,10 @@ SnackbarContent.propTypes = { * @default 'alert' */ role: PropTypes.string, + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx: PropTypes.object, }; -export default withStyles(styles, { name: 'MuiSnackbarContent' })(SnackbarContent); +export default SnackbarContent; diff --git a/packages/material-ui/src/SnackbarContent/SnackbarContent.test.js b/packages/material-ui/src/SnackbarContent/SnackbarContent.test.js index b3cd8de9c0fb49..cba0be526fe1c5 100644 --- a/packages/material-ui/src/SnackbarContent/SnackbarContent.test.js +++ b/packages/material-ui/src/SnackbarContent/SnackbarContent.test.js @@ -1,24 +1,22 @@ import * as React from 'react'; import { expect } from 'chai'; -import { createClientRender, getClasses, createMount, describeConformance } from 'test/utils'; +import { createClientRender, createMount, describeConformanceV5 } from 'test/utils'; import Paper from '../Paper'; +import classes from './snackbarContentClasses'; import SnackbarContent from './SnackbarContent'; describe('', () => { - const mount = createMount(); - let classes; const render = createClientRender(); + const mount = createMount(); - before(() => { - classes = getClasses(); - }); - - describeConformance(, () => ({ + describeConformanceV5(, () => ({ classes, inheritComponent: Paper, + render, mount, + muiName: 'MuiSnackbarContent', refInstanceof: window.HTMLDivElement, - skip: ['componentProp'], + skip: ['componentProp', 'componentsProp', 'themeVariants'], })); describe('prop: action', () => { diff --git a/packages/material-ui/src/SnackbarContent/index.d.ts b/packages/material-ui/src/SnackbarContent/index.d.ts index ab4fa3bdecb3bd..658d42f88a58ea 100644 --- a/packages/material-ui/src/SnackbarContent/index.d.ts +++ b/packages/material-ui/src/SnackbarContent/index.d.ts @@ -1,2 +1,5 @@ export { default } from './SnackbarContent'; export * from './SnackbarContent'; + +export { default as snackbarContentClasses } from './snackbarContentClasses'; +export * from './snackbarContentClasses'; diff --git a/packages/material-ui/src/SnackbarContent/index.js b/packages/material-ui/src/SnackbarContent/index.js index 4f9b0215d76545..44f55061a70824 100644 --- a/packages/material-ui/src/SnackbarContent/index.js +++ b/packages/material-ui/src/SnackbarContent/index.js @@ -1 +1,4 @@ export { default } from './SnackbarContent'; + +export { default as snackbarContentClasses } from './snackbarContentClasses'; +export * from './snackbarContentClasses'; diff --git a/packages/material-ui/src/SnackbarContent/snackbarContentClasses.d.ts b/packages/material-ui/src/SnackbarContent/snackbarContentClasses.d.ts new file mode 100644 index 00000000000000..30040f3e561412 --- /dev/null +++ b/packages/material-ui/src/SnackbarContent/snackbarContentClasses.d.ts @@ -0,0 +1,9 @@ +import { SnackbarContentClassKey } from './SnackbarContent'; + +export type SnackbarContentClasses = Record; + +declare const snackbarContentClasses: SnackbarContentClasses; + +export function getSnackbarContentUtilityClass(slot: string): string; + +export default snackbarContentClasses; diff --git a/packages/material-ui/src/SnackbarContent/snackbarContentClasses.js b/packages/material-ui/src/SnackbarContent/snackbarContentClasses.js new file mode 100644 index 00000000000000..3e082c46007793 --- /dev/null +++ b/packages/material-ui/src/SnackbarContent/snackbarContentClasses.js @@ -0,0 +1,13 @@ +import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled'; + +export function getSnackbarContentUtilityClass(slot) { + return generateUtilityClass('MuiSnackbarContent', slot); +} + +const snackbarContentClasses = generateUtilityClasses('MuiSnackbarContent', [ + 'root', + 'message', + 'action', +]); + +export default snackbarContentClasses;