From 97aac4e1d56ec4353ba952623e942892dad4c890 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 29 Jun 2020 10:40:05 +0200 Subject: [PATCH 01/81] wip --- .../components/buttons/CustomizedButtons.js | 41 +++++++++++++++++++ packages/material-ui/src/Button/Button.d.ts | 2 +- packages/material-ui/src/Button/Button.js | 2 +- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index a99fb3c96113c3..b65cf24b0bac26 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -66,6 +66,44 @@ const theme = createMuiTheme({ palette: { primary: green, }, + overrides: { + MuiButton: { + dashed: { + padding: '5px 15px', + border: "5px dashed red", + '&$disabled': { + border: `5px dashed red`, + }, + }, + // dashedPrimary: { + // color: theme.palette.primary.main, + // border: `1px solid ${fade(theme.palette.primary.main, 0.5)}`, + // '&:hover': { + // border: `1px solid ${theme.palette.primary.main}`, + // backgroundColor: fade(theme.palette.primary.main, theme.palette.action.hoverOpacity), + // // Reset on touch devices, it doesn't add specificity + // '@media (hover: none)': { + // backgroundColor: 'transparent', + // }, + // }, + // }, + // dashedSecondary: { + // color: theme.palette.secondary.main, + // border: `1px dashed ${fade(theme.palette.secondary.main, 0.5)}`, + // '&:hover': { + // border: `1px dashed ${theme.palette.secondary.main}`, + // backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.hoverOpacity), + // // Reset on touch devices, it doesn't add specificity + // '@media (hover: none)': { + // backgroundColor: 'transparent', + // }, + // }, + // '&$disabled': { + // border: `1px dashed ${theme.palette.action.disabled}`, + // }, + // }, + }, + }, }); export default function CustomizedButtons() { @@ -84,6 +122,9 @@ export default function CustomizedButtons() { + Date: Mon, 29 Jun 2020 11:47:01 +0200 Subject: [PATCH 02/81] wip --- .../components/buttons/CustomizedButtons.js | 27 ------------------- .../src/getStylesCreator/getStylesCreator.js | 2 +- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index b65cf24b0bac26..52d5346475fe4c 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -75,33 +75,6 @@ const theme = createMuiTheme({ border: `5px dashed red`, }, }, - // dashedPrimary: { - // color: theme.palette.primary.main, - // border: `1px solid ${fade(theme.palette.primary.main, 0.5)}`, - // '&:hover': { - // border: `1px solid ${theme.palette.primary.main}`, - // backgroundColor: fade(theme.palette.primary.main, theme.palette.action.hoverOpacity), - // // Reset on touch devices, it doesn't add specificity - // '@media (hover: none)': { - // backgroundColor: 'transparent', - // }, - // }, - // }, - // dashedSecondary: { - // color: theme.palette.secondary.main, - // border: `1px dashed ${fade(theme.palette.secondary.main, 0.5)}`, - // '&:hover': { - // border: `1px dashed ${theme.palette.secondary.main}`, - // backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.hoverOpacity), - // // Reset on touch devices, it doesn't add specificity - // '@media (hover: none)': { - // backgroundColor: 'transparent', - // }, - // }, - // '&$disabled': { - // border: `1px dashed ${theme.palette.action.disabled}`, - // }, - // }, }, }, }); diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 053a85973a63b0..5f48df4f735b9b 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -55,7 +55,7 @@ export default function getStylesCreator(stylesOrCreator) { } } - stylesWithOverrides[key] = deepmerge(stylesWithOverrides[key], overrides[key]); + stylesWithOverrides[key] = deepmerge(stylesWithOverrides[key] || {}, overrides[key]); }); return stylesWithOverrides; From 5c3d592dbc58f96d3f79b5692144759e774fb61c Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 30 Jun 2020 22:14:57 +0200 Subject: [PATCH 03/81] wip --- .../components/buttons/CustomizedButtons.js | 21 +++++++++ .../components/buttons/CustomizedButtons.tsx | 44 ++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index 52d5346475fe4c..2b28241aa7354e 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -1,4 +1,5 @@ import React from 'react'; +import PropTypes from 'prop-types'; import { createMuiTheme, withStyles, @@ -75,10 +76,29 @@ const theme = createMuiTheme({ border: `5px dashed red`, }, }, + tertiery: { + backgroundColor: 'yellow', + padding: 20, + } }, }, }); +function styled(BaseComponent, propTypesOverrides) { + // we are creating here wrapper, but that can be improved + const Component = React.forwardRef( + (props, ref) => { const allProps = {...props, ref}; return } + ); + + Component.displayName = BaseComponent.displayName; + Component.propTypes = { ...(BaseComponent.Naked ? BaseComponent.Naked.propTypes : BaseComponent.propTypes), ...propTypesOverrides} + return Component; +} + +const CustomButton = styled(Button, { + variant: PropTypes.oneOf(['contained', 'outlined', 'text', 'tertiery']), +}); + export default function CustomizedButtons() { const classes = useStyles(); @@ -98,6 +118,7 @@ export default function CustomizedButtons() { + Tertiery button (BaseComponent: any, propTypesOverrides: object) { + // we are creating tere wrapper, but that can be improved + const Component = React.forwardRef( + // (props, ref) => BaseComponent.render && typeof BaseComponent.render === 'function' ? BaseComponent.reder(props, ref) : BaseComponent({...props, ref}) + (props, ref) => { const allProps = {...props, ref}; return } + )as unknown as React.FunctionComponent; + + Component.displayName = BaseComponent.displayName; + Component.propTypes = { ...(BaseComponent.Naked ? BaseComponent.Naked.propTypes : BaseComponent.propTypes), ...propTypesOverrides} + return Component; +} + +type CustomButtonProps = ButtonProps & { + variant?: ButtonProps['variant'] | 'tertiary' +} + +const CustomButton = styled(Button, { + variant: PropTypes.oneOf(['contained', 'outlined', 'text', 'tertiery']), }); export default function CustomizedButtons() { @@ -88,6 +126,10 @@ export default function CustomizedButtons() { + + Tertiery button Date: Wed, 1 Jul 2020 10:12:50 +0200 Subject: [PATCH 04/81] relaxed overrides --- docs/src/pages/components/buttons/CustomizedButtons.tsx | 2 -- packages/material-ui/src/styles/overrides.d.ts | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/pages/components/buttons/CustomizedButtons.tsx b/docs/src/pages/components/buttons/CustomizedButtons.tsx index 5a27c6a19b588d..de7bd559ca5485 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.tsx +++ b/docs/src/pages/components/buttons/CustomizedButtons.tsx @@ -73,7 +73,6 @@ const theme = createMuiTheme({ }, overrides: { MuiButton: { - // @ts-ignore dashed: { padding: '5px 15px', border: "5px dashed red", @@ -81,7 +80,6 @@ const theme = createMuiTheme({ border: `5px dashed red`, }, }, - // @ts-ignore tertiery: { backgroundColor: 'yellow', padding: 20, diff --git a/packages/material-ui/src/styles/overrides.d.ts b/packages/material-ui/src/styles/overrides.d.ts index fa65fd4119ae45..c22fa4ba22c721 100644 --- a/packages/material-ui/src/styles/overrides.d.ts +++ b/packages/material-ui/src/styles/overrides.d.ts @@ -96,8 +96,10 @@ import { TooltipClassKey } from '../Tooltip'; import { TouchRippleClassKey } from '../ButtonBase/TouchRipple'; import { TypographyClassKey } from '../Typography'; +export type Extended = T | string + export type Overrides = { - [Name in keyof ComponentNameToClassKey]?: Partial>; + [Name in keyof ComponentNameToClassKey]?: Partial>>; } & { MuiCssBaseline?: { '@global'?: { From 6e0ab4d7e7bcc61a735dfb3cf47ca5fb42d20b85 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 2 Jul 2020 08:28:16 +0200 Subject: [PATCH 05/81] added additions --- .../components/buttons/CustomizedButtons.js | 4 +- .../components/buttons/CustomizedButtons.tsx | 2 +- .../src/getStylesCreator/getStylesCreator.js | 10 +- .../material-ui/src/styles/additions.d.ts | 100 ++++++++++++++++++ .../src/styles/createMuiTheme.d.ts | 3 + .../material-ui/src/styles/createMuiTheme.js | 2 + .../material-ui/src/styles/overrides.d.ts | 4 +- 7 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 packages/material-ui/src/styles/additions.d.ts diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index 2b28241aa7354e..3f66c711ca1319 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -67,7 +67,7 @@ const theme = createMuiTheme({ palette: { primary: green, }, - overrides: { + additions: { MuiButton: { dashed: { padding: '5px 15px', @@ -81,7 +81,7 @@ const theme = createMuiTheme({ padding: 20, } }, - }, + } }); function styled(BaseComponent, propTypesOverrides) { diff --git a/docs/src/pages/components/buttons/CustomizedButtons.tsx b/docs/src/pages/components/buttons/CustomizedButtons.tsx index de7bd559ca5485..5e64673f809d33 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.tsx +++ b/docs/src/pages/components/buttons/CustomizedButtons.tsx @@ -71,7 +71,7 @@ const theme = createMuiTheme({ palette: { primary: green, }, - overrides: { + additions: { MuiButton: { dashed: { padding: '5px 15px', diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 5f48df4f735b9b..dd67bd59993b5d 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -36,11 +36,12 @@ export default function getStylesCreator(stylesOrCreator) { throw err; } - if (!name || !theme.overrides || !theme.overrides[name]) { + if (!name || ((!theme.overrides || !theme.overrides[name]) && (!theme.additions || !theme.additions[name]))) { return styles; } - const overrides = theme.overrides[name]; + const additions = theme.additions[name] || {}; + const overrides = theme.overrides[name] || {}; const stylesWithOverrides = { ...styles }; Object.keys(overrides).forEach((key) => { @@ -50,6 +51,7 @@ export default function getStylesCreator(stylesOrCreator) { [ 'Material-UI: You are trying to override a style that does not exist.', `Fix the \`${key}\` key of \`theme.overrides.${name}\`.`, + 'If you intentionally wanted to add new key, please use the theme.additions option', ].join('\n'), ); } @@ -58,6 +60,10 @@ export default function getStylesCreator(stylesOrCreator) { stylesWithOverrides[key] = deepmerge(stylesWithOverrides[key] || {}, overrides[key]); }); + Object.keys(additions).forEach((key) => { + stylesWithOverrides[key] = deepmerge(stylesWithOverrides[key] || {}, additions[key]); + }); + return stylesWithOverrides; }, options: {}, diff --git a/packages/material-ui/src/styles/additions.d.ts b/packages/material-ui/src/styles/additions.d.ts new file mode 100644 index 00000000000000..9c074cf14f96db --- /dev/null +++ b/packages/material-ui/src/styles/additions.d.ts @@ -0,0 +1,100 @@ +import { StyleRules } from './withStyles'; + +export interface Additions { + MuiAppBar?: StyleRules; + MuiAvatar?: StyleRules; + MuiBackdrop?: StyleRules; + MuiBadge?: StyleRules; + MuiBottomNavigation?: StyleRules; + MuiBottomNavigationAction?: StyleRules; + MuiBreadcrumbs?: StyleRules; + MuiButton?: StyleRules; + MuiButtonBase?: StyleRules; + MuiButtonGroup?: StyleRules; + MuiCard?: StyleRules; + MuiCardActionArea?: StyleRules; + MuiCardActions?: StyleRules; + MuiCardContent?: StyleRules; + MuiCardHeader?: StyleRules; + MuiCardMedia?: StyleRules; + MuiCheckbox?: StyleRules; + MuiChip?: StyleRules; + MuiCircularProgress?: StyleRules; + MuiCollapse?: StyleRules; + MuiContainer?: StyleRules; + MuiDialog?: StyleRules; + MuiDialogActions?: StyleRules; + MuiDialogContent?: StyleRules; + MuiDialogContentText?: StyleRules; + MuiDialogTitle?: StyleRules; + MuiDivider?: StyleRules; + MuiDrawer?: StyleRules; + MuiAccordion?: StyleRules; + MuiAccordionActions?: StyleRules; + MuiAccordionDetails?: StyleRules; + MuiAccordionSummary?: StyleRules; + MuiFab?: StyleRules; + MuiFilledInput?: StyleRules; + MuiFormControl?: StyleRules; + MuiFormControlLabel?: StyleRules; + MuiFormGroup?: StyleRules; + MuiFormHelperText?: StyleRules; + MuiFormLabel?: StyleRules; + MuiGrid?: StyleRules; + MuiGridList?: StyleRules; + MuiGridListTile?: StyleRules; + MuiGridListTileBar?: StyleRules; + MuiIcon?: StyleRules; + MuiIconButton?: StyleRules; + MuiInput?: StyleRules; + MuiInputAdornment?: StyleRules; + MuiInputBase?: StyleRules; + MuiInputLabel?: StyleRules; + MuiLinearProgress?: StyleRules; + MuiLink?: StyleRules; + MuiList?: StyleRules; + MuiListItem?: StyleRules; + MuiListItemAvatar?: StyleRules; + MuiListItemIcon?: StyleRules; + MuiListItemSecondaryAction?: StyleRules; + MuiListItemText?: StyleRules; + MuiListSubheader?: StyleRules; + MuiMenu?: StyleRules; + MuiMenuItem?: StyleRules; + MuiMobileStepper?: StyleRules; + MuiNativeSelect?: StyleRules; + MuiOutlinedInput?: StyleRules; + MuiPaper?: StyleRules; + MuiPopover?: StyleRules; + MuiRadio?: StyleRules; + MuiScopedCssBaseline?: StyleRules; + MuiSelect?: StyleRules; + MuiSlider?: StyleRules; + MuiSnackbar?: StyleRules; + MuiSnackbarContent?: StyleRules; + MuiStep?: StyleRules; + MuiStepButton?: StyleRules; + MuiStepConnector?: StyleRules; + MuiStepContent?: StyleRules; + MuiStepIcon?: StyleRules; + MuiStepLabel?: StyleRules; + MuiStepper?: StyleRules; + MuiSvgIcon?: StyleRules; + MuiSwitch?: StyleRules; + MuiTab?: StyleRules; + MuiTable?: StyleRules; + MuiTableBody?: StyleRules; + MuiTableCell?: StyleRules; + MuiTableContainer?: StyleRules; + MuiTableFooter?: StyleRules; + MuiTableHead?: StyleRules; + MuiTablePagination?: StyleRules; + MuiTableRow?: StyleRules; + MuiTableSortLabel?: StyleRules; + MuiTabs?: StyleRules; + MuiTextField?: StyleRules; + MuiToolbar?: StyleRules; + MuiTooltip?: StyleRules; + MuiTouchRipple?: StyleRules; + MuiTypography?: StyleRules; +} diff --git a/packages/material-ui/src/styles/createMuiTheme.d.ts b/packages/material-ui/src/styles/createMuiTheme.d.ts index 27b380c35e0870..2f982e74f0d55b 100644 --- a/packages/material-ui/src/styles/createMuiTheme.d.ts +++ b/packages/material-ui/src/styles/createMuiTheme.d.ts @@ -8,12 +8,14 @@ import { Spacing, SpacingOptions } from './createSpacing'; import { Transitions, TransitionsOptions } from './transitions'; import { ZIndex, ZIndexOptions } from './zIndex'; import { Overrides } from './overrides'; +import { Additions } from './additions'; import { ComponentsProps } from './props'; export type Direction = 'ltr' | 'rtl'; export interface ThemeOptions { shape?: ShapeOptions; + additions?: Additions; breakpoints?: BreakpointsOptions; direction?: Direction; mixins?: MixinsOptions; @@ -30,6 +32,7 @@ export interface ThemeOptions { export interface Theme { shape: Shape; + additions?: Additions; breakpoints: Breakpoints; direction: Direction; mixins: Mixins; diff --git a/packages/material-ui/src/styles/createMuiTheme.js b/packages/material-ui/src/styles/createMuiTheme.js index b679500db0bca4..c3b675b75870ef 100644 --- a/packages/material-ui/src/styles/createMuiTheme.js +++ b/packages/material-ui/src/styles/createMuiTheme.js @@ -25,6 +25,7 @@ function createMuiTheme(options = {}, ...args) { let muiTheme = deepmerge( { + additions: {}, breakpoints, direction: 'ltr', mixins: createMixins(breakpoints, spacing, mixinsInput), @@ -95,6 +96,7 @@ function createMuiTheme(options = {}, ...args) { }; traverse(muiTheme.overrides); + traverse(muiTheme.additions); } return muiTheme; diff --git a/packages/material-ui/src/styles/overrides.d.ts b/packages/material-ui/src/styles/overrides.d.ts index c22fa4ba22c721..fa65fd4119ae45 100644 --- a/packages/material-ui/src/styles/overrides.d.ts +++ b/packages/material-ui/src/styles/overrides.d.ts @@ -96,10 +96,8 @@ import { TooltipClassKey } from '../Tooltip'; import { TouchRippleClassKey } from '../ButtonBase/TouchRipple'; import { TypographyClassKey } from '../Typography'; -export type Extended = T | string - export type Overrides = { - [Name in keyof ComponentNameToClassKey]?: Partial>>; + [Name in keyof ComponentNameToClassKey]?: Partial>; } & { MuiCssBaseline?: { '@global'?: { From 5c8364c06108cf21a7403270047dd2fd011df074 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 2 Jul 2020 08:38:40 +0200 Subject: [PATCH 06/81] cleanup --- .../components/buttons/CustomizedButtons.js | 18 +-------------- .../components/buttons/CustomizedButtons.tsx | 23 +------------------ 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index 3f66c711ca1319..a4354bdef83ca8 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -84,21 +84,6 @@ const theme = createMuiTheme({ } }); -function styled(BaseComponent, propTypesOverrides) { - // we are creating here wrapper, but that can be improved - const Component = React.forwardRef( - (props, ref) => { const allProps = {...props, ref}; return } - ); - - Component.displayName = BaseComponent.displayName; - Component.propTypes = { ...(BaseComponent.Naked ? BaseComponent.Naked.propTypes : BaseComponent.propTypes), ...propTypesOverrides} - return Component; -} - -const CustomButton = styled(Button, { - variant: PropTypes.oneOf(['contained', 'outlined', 'text', 'tertiery']), -}); - export default function CustomizedButtons() { const classes = useStyles(); @@ -116,9 +101,8 @@ export default function CustomizedButtons() { Theme Provider - Tertiery button (BaseComponent: any, propTypesOverrides: object) { - // we are creating tere wrapper, but that can be improved - const Component = React.forwardRef( - // (props, ref) => BaseComponent.render && typeof BaseComponent.render === 'function' ? BaseComponent.reder(props, ref) : BaseComponent({...props, ref}) - (props, ref) => { const allProps = {...props, ref}; return } - )as unknown as React.FunctionComponent; - - Component.displayName = BaseComponent.displayName; - Component.propTypes = { ...(BaseComponent.Naked ? BaseComponent.Naked.propTypes : BaseComponent.propTypes), ...propTypesOverrides} - return Component; -} - -type CustomButtonProps = ButtonProps & { - variant?: ButtonProps['variant'] | 'tertiary' -} - -const CustomButton = styled(Button, { - variant: PropTypes.oneOf(['contained', 'outlined', 'text', 'tertiery']), -}); - export default function CustomizedButtons() { const classes = useStyles(); @@ -125,9 +105,8 @@ export default function CustomizedButtons() { Theme Provider - Tertiery button Date: Thu, 2 Jul 2020 09:02:39 +0200 Subject: [PATCH 07/81] cleanup --- docs/src/pages/components/buttons/CustomizedButtons.js | 1 - docs/src/pages/components/buttons/CustomizedButtons.tsx | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index a4354bdef83ca8..e1a837ef82b81b 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { createMuiTheme, withStyles, diff --git a/docs/src/pages/components/buttons/CustomizedButtons.tsx b/docs/src/pages/components/buttons/CustomizedButtons.tsx index 0833afb07575e0..2dbf9ceb03591e 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.tsx +++ b/docs/src/pages/components/buttons/CustomizedButtons.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { createMuiTheme, createStyles, @@ -8,7 +7,7 @@ import { Theme, ThemeProvider, } from '@material-ui/core/styles'; -import Button, { ButtonProps } from '@material-ui/core/Button'; +import Button from '@material-ui/core/Button'; import { green, purple } from '@material-ui/core/colors'; const BootstrapButton = withStyles({ From 1755be6d8532a492a318b6db7793bc9e35bf4f64 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 2 Jul 2020 09:58:22 +0200 Subject: [PATCH 08/81] prettier --- docs/src/pages/components/buttons/CustomizedButtons.js | 6 +++--- docs/src/pages/components/buttons/CustomizedButtons.tsx | 4 ++-- .../src/getStylesCreator/getStylesCreator.js | 6 +++++- packages/material-ui/src/Button/Button.js | 5 ++++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index e1a837ef82b81b..b745bae6f13b16 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -70,7 +70,7 @@ const theme = createMuiTheme({ MuiButton: { dashed: { padding: '5px 15px', - border: "5px dashed red", + border: '5px dashed red', '&$disabled': { border: `5px dashed red`, }, @@ -78,9 +78,9 @@ const theme = createMuiTheme({ tertiery: { backgroundColor: 'yellow', padding: 20, - } + }, }, - } + }, }); export default function CustomizedButtons() { diff --git a/docs/src/pages/components/buttons/CustomizedButtons.tsx b/docs/src/pages/components/buttons/CustomizedButtons.tsx index 2dbf9ceb03591e..6c2be5db3a13a7 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.tsx +++ b/docs/src/pages/components/buttons/CustomizedButtons.tsx @@ -74,7 +74,7 @@ const theme = createMuiTheme({ MuiButton: { dashed: { padding: '5px 15px', - border: "5px dashed red", + border: '5px dashed red', '&$disabled': { border: `5px dashed red`, }, @@ -82,7 +82,7 @@ const theme = createMuiTheme({ tertiery: { backgroundColor: 'yellow', padding: 20, - } + }, }, }, }); diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index dd67bd59993b5d..ab6f25ada87f85 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -36,7 +36,11 @@ export default function getStylesCreator(stylesOrCreator) { throw err; } - if (!name || ((!theme.overrides || !theme.overrides[name]) && (!theme.additions || !theme.additions[name]))) { + if ( + !name || + ((!theme.overrides || !theme.overrides[name]) && + (!theme.additions || !theme.additions[name])) + ) { return styles; } diff --git a/packages/material-ui/src/Button/Button.js b/packages/material-ui/src/Button/Button.js index 9b8744964aca2c..f3226331242d01 100644 --- a/packages/material-ui/src/Button/Button.js +++ b/packages/material-ui/src/Button/Button.js @@ -409,7 +409,10 @@ Button.propTypes = { /** * The variant to use. */ - variant: PropTypes.oneOfType([PropTypes.oneOf(['contained', 'outlined', 'text']), PropTypes.string]), + variant: PropTypes.oneOfType([ + PropTypes.oneOf(['contained', 'outlined', 'text']), + PropTypes.string, + ]), }; export default withStyles(styles, { name: 'MuiButton' })(Button); From 8c0ae69ec219a7c87ca79b5158e1a47e50cfb903 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 4 Jul 2020 16:53:02 +0200 Subject: [PATCH 09/81] wip --- .../components/buttons/CustomizedButtons.js | 31 +++++++++++++++++++ .../src/withStyles/withStyles.js | 25 ++++++++++++++- packages/material-ui-utils/src/deepmerge.js | 1 + .../src/styles/createMuiTheme.d.ts | 2 ++ .../material-ui/src/styles/createMuiTheme.js | 1 + 5 files changed, 59 insertions(+), 1 deletion(-) diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index b745bae6f13b16..498096fb852356 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -81,6 +81,34 @@ const theme = createMuiTheme({ }, }, }, + variants: { + MuiButton: [ + { + trigger: (props) => props.variant === 'red', + styles: { + color: 'red' + } + }, + { + trigger: (props) => props.size === 'xxsmall', + styles: { + fontSize: '5px' + } + }, + { + trigger: (props) => props.toggle, + styles: { + background: 'green' + } + }, + { + trigger: (props) => props.toggle === 'red', + styles: { + backgroundColor: 'red' + } + } + ], + } }); export default function CustomizedButtons() { @@ -102,6 +130,9 @@ export default function CustomizedButtons() { + (Component) => { ...stylesOptions, }); + // console.log(stylesOrCreator); + // if(defaultTheme) { + // console.log(defaultTheme.variants); + // } + const WithStyles = React.forwardRef(function WithStyles(props, ref) { const { classes: classesProp, innerRef, ...other } = props; // The wrapper receives only user supplied props, which could be a subset of @@ -57,7 +62,25 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { // name and withTheme are invariant in the outer scope // eslint-disable-next-line react-hooks/rules-of-hooks theme = useTheme() || defaultTheme; - + if(theme && theme.variants && theme.variants[name]) { + + const arr = theme.variants[name]; + const styles = arr.reduce((acc, curr) => { + // TODO: add state + if(curr.trigger(props)) { + acc = { ...acc, ...curr.styles } // TODO: deepmerge + } + return acc; + }, {}); + + + const useVariantStyles = makeStyles({ root: styles }); + + + const variantClasses = useVariantStyles(); + console.log(variantClasses.root); + classes.root = classes.root + " " + variantClasses.root; // merge styles first :\ + } if (name) { more = getThemeProps({ theme, name, props: other }); } diff --git a/packages/material-ui-utils/src/deepmerge.js b/packages/material-ui-utils/src/deepmerge.js index 3d6cf634730981..2bca86234b4669 100644 --- a/packages/material-ui-utils/src/deepmerge.js +++ b/packages/material-ui-utils/src/deepmerge.js @@ -5,6 +5,7 @@ export function isPlainObject(item) { export default function deepmerge(target, source, options = { clone: true }) { const output = options.clone ? { ...target } : target; + // TODO: add merging of arrays if (isPlainObject(target) && isPlainObject(source)) { Object.keys(source).forEach((key) => { // Avoid prototype pollution diff --git a/packages/material-ui/src/styles/createMuiTheme.d.ts b/packages/material-ui/src/styles/createMuiTheme.d.ts index 2f982e74f0d55b..613a9b2bd5e7e3 100644 --- a/packages/material-ui/src/styles/createMuiTheme.d.ts +++ b/packages/material-ui/src/styles/createMuiTheme.d.ts @@ -16,6 +16,7 @@ export type Direction = 'ltr' | 'rtl'; export interface ThemeOptions { shape?: ShapeOptions; additions?: Additions; + variants?: any; breakpoints?: BreakpointsOptions; direction?: Direction; mixins?: MixinsOptions; @@ -39,6 +40,7 @@ export interface Theme { overrides?: Overrides; palette: Palette; props?: ComponentsProps; + variants: any; shadows: Shadows; spacing: Spacing; transitions: Transitions; diff --git a/packages/material-ui/src/styles/createMuiTheme.js b/packages/material-ui/src/styles/createMuiTheme.js index c3b675b75870ef..82e367f9467ab2 100644 --- a/packages/material-ui/src/styles/createMuiTheme.js +++ b/packages/material-ui/src/styles/createMuiTheme.js @@ -37,6 +37,7 @@ function createMuiTheme(options = {}, ...args) { spacing, shape, transitions, + variants: {}, zIndex, }, other, From 036a172d79605e3af88e334e5f0a3fde89f02b43 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 5 Jul 2020 07:30:32 +0200 Subject: [PATCH 10/81] another alternative --- .../components/buttons/CustomizedButtons.js | 20 ++++++++++ .../src/getStylesCreator/getStylesCreator.js | 24 ++++++++++++ .../src/withStyles/withStyles.js | 37 ++++++++----------- .../src/styles/createMuiTheme.d.ts | 2 + packages/material-ui/src/styles/variants.d.ts | 8 ++++ 5 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 packages/material-ui/src/styles/variants.d.ts diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index 498096fb852356..0ed11d7209e0f8 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -108,6 +108,23 @@ const theme = createMuiTheme({ } } ], + }, + variantsV2: { + MuiButton: [ + { + matcher: { variant: 'yellow' }, + styles: { + color: 'yellow', + background: 'grey', + } + }, + { + matcher: { size: 'xxlarge' }, + styles: { + fontSize: '50px', + } + }, + ], } }); @@ -133,6 +150,9 @@ export default function CustomizedButtons() { + { + return string.charAt(0).toUpperCase() + string.slice(1) +} + +// This should be defined somehwere per component +// ideally each component would define this for itself... +const propsToClassKey = (matcher) => { + let classKey = matcher.variant ? matcher.variant : ''; + if(matcher.color) { + classKey += capitalize(matcher.color); + } + if(matcher.size) { + classKey += (classKey.length === 0 ? 's' : 'S') + `ize${capitalize(matcher.size)}`; + } + return classKey; +} + export default function getStylesCreator(stylesOrCreator) { const themingEnabled = typeof stylesOrCreator === 'function'; @@ -46,6 +63,7 @@ export default function getStylesCreator(stylesOrCreator) { const additions = theme.additions[name] || {}; const overrides = theme.overrides[name] || {}; + const variants = theme.variantsV2[name] || []; const stylesWithOverrides = { ...styles }; Object.keys(overrides).forEach((key) => { @@ -68,6 +86,12 @@ export default function getStylesCreator(stylesOrCreator) { stylesWithOverrides[key] = deepmerge(stylesWithOverrides[key] || {}, additions[key]); }); + variants.forEach(definition => { + const classKey = propsToClassKey(definition.matcher); + console.log(classKey); + stylesWithOverrides[classKey] = deepmerge(stylesWithOverrides[classKey] || {}, definition.styles); + }) + return stylesWithOverrides; }, options: {}, diff --git a/packages/material-ui-styles/src/withStyles/withStyles.js b/packages/material-ui-styles/src/withStyles/withStyles.js index d2078c22912e21..9d403fd5860d77 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.js @@ -43,17 +43,13 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { ...stylesOptions, }); - // console.log(stylesOrCreator); - // if(defaultTheme) { - // console.log(defaultTheme.variants); - // } - const WithStyles = React.forwardRef(function WithStyles(props, ref) { const { classes: classesProp, innerRef, ...other } = props; // The wrapper receives only user supplied props, which could be a subset of // the actual props Component might receive due to merging with defaultProps. // So copying it here would give us the same result in the wrapper as well. - const classes = useStyles({ ...Component.defaultProps, ...props }); + const allProps = { ...Component.defaultProps, ...props }; + const classes = useStyles(allProps); let theme; let more = other; @@ -62,25 +58,24 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { // name and withTheme are invariant in the outer scope // eslint-disable-next-line react-hooks/rules-of-hooks theme = useTheme() || defaultTheme; - if(theme && theme.variants && theme.variants[name]) { + // if(theme && theme.variants && theme.variants[name]) { - const arr = theme.variants[name]; - const styles = arr.reduce((acc, curr) => { - // TODO: add state - if(curr.trigger(props)) { - acc = { ...acc, ...curr.styles } // TODO: deepmerge - } - return acc; - }, {}); + // const arr = theme.variants[name]; + // const styles = arr.reduce((acc, curr) => { + // // TODO: add state + // if(curr.trigger(allProps)) { + // acc = { ...acc, ...curr.styles } // TODO: deepmerge + // } + // return acc; + // }, {}); - const useVariantStyles = makeStyles({ root: styles }); - + // const useVariantStyles = makeStyles({ root: styles }); - const variantClasses = useVariantStyles(); - console.log(variantClasses.root); - classes.root = classes.root + " " + variantClasses.root; // merge styles first :\ - } + // const variantClasses = useVariantStyles(); + + // classes.root = classes.root + " " + variantClasses.root; // merge styles first :\ + // } if (name) { more = getThemeProps({ theme, name, props: other }); } diff --git a/packages/material-ui/src/styles/createMuiTheme.d.ts b/packages/material-ui/src/styles/createMuiTheme.d.ts index 613a9b2bd5e7e3..30b61b3bffd782 100644 --- a/packages/material-ui/src/styles/createMuiTheme.d.ts +++ b/packages/material-ui/src/styles/createMuiTheme.d.ts @@ -9,6 +9,7 @@ import { Transitions, TransitionsOptions } from './transitions'; import { ZIndex, ZIndexOptions } from './zIndex'; import { Overrides } from './overrides'; import { Additions } from './additions'; +import { Variants } from './variants'; import { ComponentsProps } from './props'; export type Direction = 'ltr' | 'rtl'; @@ -17,6 +18,7 @@ export interface ThemeOptions { shape?: ShapeOptions; additions?: Additions; variants?: any; + variantsV2?: Variants; breakpoints?: BreakpointsOptions; direction?: Direction; mixins?: MixinsOptions; diff --git a/packages/material-ui/src/styles/variants.d.ts b/packages/material-ui/src/styles/variants.d.ts new file mode 100644 index 00000000000000..f99ebbff55e8d1 --- /dev/null +++ b/packages/material-ui/src/styles/variants.d.ts @@ -0,0 +1,8 @@ +import { ComponentsPropsList } from './props'; + +export type Variants = { + [Name in keyof ComponentsPropsList]?: { + matcher: Partial, + styles: string; + } +}; \ No newline at end of file From 1b94f50dcccc8e7c47ee4fe8068be4a631b1adb6 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 5 Jul 2020 07:32:15 +0200 Subject: [PATCH 11/81] Update packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js --- .../material-ui-styles/src/getStylesCreator/getStylesCreator.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 7da43e322c4c26..161c7ae2563336 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -88,7 +88,6 @@ export default function getStylesCreator(stylesOrCreator) { variants.forEach(definition => { const classKey = propsToClassKey(definition.matcher); - console.log(classKey); stylesWithOverrides[classKey] = deepmerge(stylesWithOverrides[classKey] || {}, definition.styles); }) From 9370c1ce57212d7e7e071ea8a1617ae76f30a467 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 5 Jul 2020 07:37:45 +0200 Subject: [PATCH 12/81] comb of props --- docs/src/pages/components/buttons/CustomizedButtons.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index 0ed11d7209e0f8..cd896c2230d564 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -112,10 +112,10 @@ const theme = createMuiTheme({ variantsV2: { MuiButton: [ { - matcher: { variant: 'yellow' }, + matcher: { variant: 'dashed', color: 'yellow' }, styles: { - color: 'yellow', - background: 'grey', + padding: '5px 15px', + border: '5px dashed yellow', } }, { @@ -150,7 +150,7 @@ export default function CustomizedButtons() { - From df600989c95f7e58b1058b87d4d663ef0777e094 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 5 Jul 2020 16:32:07 +0200 Subject: [PATCH 13/81] Update packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js --- .../material-ui-styles/src/getStylesCreator/getStylesCreator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 161c7ae2563336..91eb7dbfaca832 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -5,7 +5,7 @@ const capitalize = (string) => { return string.charAt(0).toUpperCase() + string.slice(1) } -// This should be defined somehwere per component +// This should be defined somewhere per component // ideally each component would define this for itself... const propsToClassKey = (matcher) => { let classKey = matcher.variant ? matcher.variant : ''; From f43077010484b40f95c81fe868d3979aa195f8b5 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 6 Jul 2020 08:42:36 +0200 Subject: [PATCH 14/81] cleanup --- docs/pages/api-docs/button.md | 6 +- .../buttons/CustomVariantButtons.js | 62 +++++++++++ .../buttons/CustomVariantButtons.tsx | 62 +++++++++++ .../components/buttons/CustomizedButtons.js | 69 ------------ .../components/buttons/CustomizedButtons.tsx | 18 ---- docs/src/pages/components/buttons/buttons.md | 6 ++ .../src/getStylesCreator/getStylesCreator.js | 35 +++--- .../src/withStyles/withStyles.js | 18 ---- packages/material-ui/src/Button/Button.d.ts | 4 +- packages/material-ui/src/Button/Button.js | 12 ++- .../material-ui/src/styles/additions.d.ts | 100 ------------------ .../src/styles/createMuiTheme.d.ts | 8 +- .../material-ui/src/styles/createMuiTheme.js | 1 - packages/material-ui/src/styles/variants.d.ts | 17 ++- 14 files changed, 173 insertions(+), 245 deletions(-) create mode 100644 docs/src/pages/components/buttons/CustomVariantButtons.js create mode 100644 docs/src/pages/components/buttons/CustomVariantButtons.tsx delete mode 100644 packages/material-ui/src/styles/additions.d.ts diff --git a/docs/pages/api-docs/button.md b/docs/pages/api-docs/button.md index fc33f6641acddd..35c102f4902bc2 100644 --- a/docs/pages/api-docs/button.md +++ b/docs/pages/api-docs/button.md @@ -30,7 +30,7 @@ The `MuiButton` name can be used for providing [default props](/customization/gl |:-----|:-----|:--------|:------------| | children | node | | The content of the button. | | classes | object | | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. | -| color | 'default'
| 'inherit'
| 'primary'
| 'secondary'
| 'default' | The color of the component. It supports those theme colors that make sense for this component. | +| color | 'default'
| 'inherit'
| 'primary'
| 'secondary'
| string
| 'default' | The color of the component. It supports those theme colors that make sense for this component. | | component | elementType | 'button' | The component used for the root node. Either a string to use a HTML element or a component. | | disabled | bool | false | If `true`, the button will be disabled. | | disableElevation | bool | false | If `true`, no elevation is used. | @@ -39,9 +39,9 @@ The `MuiButton` name can be used for providing [default props](/customization/gl | endIcon | node | | Element placed after the children. | | fullWidth | bool | false | If `true`, the button will take up the full width of its container. | | href | string | | The URL to link to when the button is clicked. If defined, an `a` element will be used as the root node. | -| size | 'large'
| 'medium'
| 'small'
| 'medium' | The size of the button. `small` is equivalent to the dense button styling. | +| size | 'large'
| 'medium'
| 'small'
| string
| 'medium' | The size of the button. `small` is equivalent to the dense button styling. | | startIcon | node | | Element placed before the children. | -| variant | 'contained'
| 'outlined'
| 'text'
| 'text' | The variant to use. | +| variant | 'contained'
| 'outlined'
| 'text'
| string
| 'text' | The variant to use. | The `ref` is forwarded to the root element. diff --git a/docs/src/pages/components/buttons/CustomVariantButtons.js b/docs/src/pages/components/buttons/CustomVariantButtons.js new file mode 100644 index 00000000000000..6d21ca85574aed --- /dev/null +++ b/docs/src/pages/components/buttons/CustomVariantButtons.js @@ -0,0 +1,62 @@ +import React from 'react'; +import { + createMuiTheme, + makeStyles, + ThemeProvider, +} from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; + +const useStyles = makeStyles((theme) => ({ + margin: { + margin: theme.spacing(1), + }, +})); + +const theme = createMuiTheme({ + variants: { + MuiButton: [ + { + matcher: { variant: 'dashed' }, + styles: { + padding: '5px 15px', + border: '5px dashed grey', + }, + }, + { + matcher: { variant: 'dashed', color: 'teal' }, + styles: { + border: '5px dashed teal', + }, + }, + { + matcher: { size: 'xxlarge' }, + styles: (theme) => ({ + fontSize: theme.typography.pxToRem(20), + }), + }, + ], + }, +}); + +export default function CustomVariantButtons() { + const classes = useStyles(); + + return ( + + + + + + ); +} diff --git a/docs/src/pages/components/buttons/CustomVariantButtons.tsx b/docs/src/pages/components/buttons/CustomVariantButtons.tsx new file mode 100644 index 00000000000000..737af2ec06ba9c --- /dev/null +++ b/docs/src/pages/components/buttons/CustomVariantButtons.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { + createMuiTheme, + makeStyles, + ThemeProvider, +} from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; + +const useStyles = makeStyles((theme) => ({ + margin: { + margin: theme.spacing(1), + }, +})); + +const theme = createMuiTheme({ + variants: { + MuiButton: [ + { + matcher: { variant: 'dashed' }, + styles: { + padding: '5px 15px', + border: '5px dashed grey', + }, + }, + { + matcher: { variant: 'dashed', color: 'teal' }, + styles: { + border: '5px dashed teal', + }, + }, + { + matcher: { size: 'xxlarge' }, + styles: { + fontSize: '50px', + }, + }, + ], + }, +}); + +export default function CustomizedButtons() { + const classes = useStyles(); + + return ( + + + + + + ); +} diff --git a/docs/src/pages/components/buttons/CustomizedButtons.js b/docs/src/pages/components/buttons/CustomizedButtons.js index cd896c2230d564..a99fb3c96113c3 100644 --- a/docs/src/pages/components/buttons/CustomizedButtons.js +++ b/docs/src/pages/components/buttons/CustomizedButtons.js @@ -66,66 +66,6 @@ const theme = createMuiTheme({ palette: { primary: green, }, - additions: { - MuiButton: { - dashed: { - padding: '5px 15px', - border: '5px dashed red', - '&$disabled': { - border: `5px dashed red`, - }, - }, - tertiery: { - backgroundColor: 'yellow', - padding: 20, - }, - }, - }, - variants: { - MuiButton: [ - { - trigger: (props) => props.variant === 'red', - styles: { - color: 'red' - } - }, - { - trigger: (props) => props.size === 'xxsmall', - styles: { - fontSize: '5px' - } - }, - { - trigger: (props) => props.toggle, - styles: { - background: 'green' - } - }, - { - trigger: (props) => props.toggle === 'red', - styles: { - backgroundColor: 'red' - } - } - ], - }, - variantsV2: { - MuiButton: [ - { - matcher: { variant: 'dashed', color: 'yellow' }, - styles: { - padding: '5px 15px', - border: '5px dashed yellow', - } - }, - { - matcher: { size: 'xxlarge' }, - styles: { - fontSize: '50px', - } - }, - ], - } }); export default function CustomizedButtons() { @@ -144,15 +84,6 @@ export default function CustomizedButtons() { - - - Theme Provider - { - return string.charAt(0).toUpperCase() + string.slice(1) -} + return string.charAt(0).toUpperCase() + string.slice(1); +}; -// This should be defined somewhere per component -// ideally each component would define this for itself... const propsToClassKey = (matcher) => { let classKey = matcher.variant ? matcher.variant : ''; - if(matcher.color) { - classKey += capitalize(matcher.color); + if (matcher.color) { + classKey += classKey.length === 0 ? matcher.color : capitalize(matcher.color); } - if(matcher.size) { + if (matcher.size) { classKey += (classKey.length === 0 ? 's' : 'S') + `ize${capitalize(matcher.size)}`; } return classKey; -} +}; export default function getStylesCreator(stylesOrCreator) { const themingEnabled = typeof stylesOrCreator === 'function'; @@ -55,15 +53,13 @@ export default function getStylesCreator(stylesOrCreator) { if ( !name || - ((!theme.overrides || !theme.overrides[name]) && - (!theme.additions || !theme.additions[name])) + ((!theme.overrides || !theme.overrides[name]) && (!theme.variants || !theme.variants[name])) ) { return styles; } - const additions = theme.additions[name] || {}; const overrides = theme.overrides[name] || {}; - const variants = theme.variantsV2[name] || []; + const variants = theme.variants[name] || []; const stylesWithOverrides = { ...styles }; Object.keys(overrides).forEach((key) => { @@ -73,7 +69,7 @@ export default function getStylesCreator(stylesOrCreator) { [ 'Material-UI: You are trying to override a style that does not exist.', `Fix the \`${key}\` key of \`theme.overrides.${name}\`.`, - 'If you intentionally wanted to add new key, please use the theme.additions option', + 'If you intentionally wanted to add new key, please use the theme.variants option', ].join('\n'), ); } @@ -81,15 +77,12 @@ export default function getStylesCreator(stylesOrCreator) { stylesWithOverrides[key] = deepmerge(stylesWithOverrides[key] || {}, overrides[key]); }); - - Object.keys(additions).forEach((key) => { - stylesWithOverrides[key] = deepmerge(stylesWithOverrides[key] || {}, additions[key]); - }); - - variants.forEach(definition => { + variants.forEach((definition) => { const classKey = propsToClassKey(definition.matcher); - stylesWithOverrides[classKey] = deepmerge(stylesWithOverrides[classKey] || {}, definition.styles); - }) + const styles = + typeof definition.styles === 'function' ? definition.styles(theme) : definition.styles; + stylesWithOverrides[classKey] = deepmerge(stylesWithOverrides[classKey] || {}, styles); + }); return stylesWithOverrides; }, diff --git a/packages/material-ui-styles/src/withStyles/withStyles.js b/packages/material-ui-styles/src/withStyles/withStyles.js index 9d403fd5860d77..d83ac4fc01b58e 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.js @@ -58,24 +58,6 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { // name and withTheme are invariant in the outer scope // eslint-disable-next-line react-hooks/rules-of-hooks theme = useTheme() || defaultTheme; - // if(theme && theme.variants && theme.variants[name]) { - - // const arr = theme.variants[name]; - // const styles = arr.reduce((acc, curr) => { - // // TODO: add state - // if(curr.trigger(allProps)) { - // acc = { ...acc, ...curr.styles } // TODO: deepmerge - // } - // return acc; - // }, {}); - - - // const useVariantStyles = makeStyles({ root: styles }); - - // const variantClasses = useVariantStyles(); - - // classes.root = classes.root + " " + variantClasses.root; // merge styles first :\ - // } if (name) { more = getThemeProps({ theme, name, props: other }); } diff --git a/packages/material-ui/src/Button/Button.d.ts b/packages/material-ui/src/Button/Button.d.ts index 23df5b13866e6f..039ae127f9e09d 100644 --- a/packages/material-ui/src/Button/Button.d.ts +++ b/packages/material-ui/src/Button/Button.d.ts @@ -14,7 +14,7 @@ export type ButtonTypeMap< /** * The color of the component. It supports those theme colors that make sense for this component. */ - color?: PropTypes.Color; + color?: PropTypes.Color | string; /** * If `true`, the button will be disabled. */ @@ -44,7 +44,7 @@ export type ButtonTypeMap< * The size of the button. * `small` is equivalent to the dense button styling. */ - size?: 'small' | 'medium' | 'large'; + size?: 'small' | 'medium' | 'large' | string; /** * Element placed before the children. */ diff --git a/packages/material-ui/src/Button/Button.js b/packages/material-ui/src/Button/Button.js index f3226331242d01..f8449c917fcd69 100644 --- a/packages/material-ui/src/Button/Button.js +++ b/packages/material-ui/src/Button/Button.js @@ -351,7 +351,10 @@ Button.propTypes = { /** * The color of the component. It supports those theme colors that make sense for this component. */ - color: PropTypes.oneOf(['default', 'inherit', 'primary', 'secondary']), + color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.oneOf(['default', 'inherit', 'primary', 'secondary']), + PropTypes.string, + ]), /** * The component used for the root node. * Either a string to use a HTML element or a component. @@ -397,7 +400,10 @@ Button.propTypes = { * The size of the button. * `small` is equivalent to the dense button styling. */ - size: PropTypes.oneOf(['large', 'medium', 'small']), + size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.oneOf(['large', 'medium', 'small']), + PropTypes.string, + ]), /** * Element placed before the children. */ @@ -409,7 +415,7 @@ Button.propTypes = { /** * The variant to use. */ - variant: PropTypes.oneOfType([ + variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ PropTypes.oneOf(['contained', 'outlined', 'text']), PropTypes.string, ]), diff --git a/packages/material-ui/src/styles/additions.d.ts b/packages/material-ui/src/styles/additions.d.ts deleted file mode 100644 index 9c074cf14f96db..00000000000000 --- a/packages/material-ui/src/styles/additions.d.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { StyleRules } from './withStyles'; - -export interface Additions { - MuiAppBar?: StyleRules; - MuiAvatar?: StyleRules; - MuiBackdrop?: StyleRules; - MuiBadge?: StyleRules; - MuiBottomNavigation?: StyleRules; - MuiBottomNavigationAction?: StyleRules; - MuiBreadcrumbs?: StyleRules; - MuiButton?: StyleRules; - MuiButtonBase?: StyleRules; - MuiButtonGroup?: StyleRules; - MuiCard?: StyleRules; - MuiCardActionArea?: StyleRules; - MuiCardActions?: StyleRules; - MuiCardContent?: StyleRules; - MuiCardHeader?: StyleRules; - MuiCardMedia?: StyleRules; - MuiCheckbox?: StyleRules; - MuiChip?: StyleRules; - MuiCircularProgress?: StyleRules; - MuiCollapse?: StyleRules; - MuiContainer?: StyleRules; - MuiDialog?: StyleRules; - MuiDialogActions?: StyleRules; - MuiDialogContent?: StyleRules; - MuiDialogContentText?: StyleRules; - MuiDialogTitle?: StyleRules; - MuiDivider?: StyleRules; - MuiDrawer?: StyleRules; - MuiAccordion?: StyleRules; - MuiAccordionActions?: StyleRules; - MuiAccordionDetails?: StyleRules; - MuiAccordionSummary?: StyleRules; - MuiFab?: StyleRules; - MuiFilledInput?: StyleRules; - MuiFormControl?: StyleRules; - MuiFormControlLabel?: StyleRules; - MuiFormGroup?: StyleRules; - MuiFormHelperText?: StyleRules; - MuiFormLabel?: StyleRules; - MuiGrid?: StyleRules; - MuiGridList?: StyleRules; - MuiGridListTile?: StyleRules; - MuiGridListTileBar?: StyleRules; - MuiIcon?: StyleRules; - MuiIconButton?: StyleRules; - MuiInput?: StyleRules; - MuiInputAdornment?: StyleRules; - MuiInputBase?: StyleRules; - MuiInputLabel?: StyleRules; - MuiLinearProgress?: StyleRules; - MuiLink?: StyleRules; - MuiList?: StyleRules; - MuiListItem?: StyleRules; - MuiListItemAvatar?: StyleRules; - MuiListItemIcon?: StyleRules; - MuiListItemSecondaryAction?: StyleRules; - MuiListItemText?: StyleRules; - MuiListSubheader?: StyleRules; - MuiMenu?: StyleRules; - MuiMenuItem?: StyleRules; - MuiMobileStepper?: StyleRules; - MuiNativeSelect?: StyleRules; - MuiOutlinedInput?: StyleRules; - MuiPaper?: StyleRules; - MuiPopover?: StyleRules; - MuiRadio?: StyleRules; - MuiScopedCssBaseline?: StyleRules; - MuiSelect?: StyleRules; - MuiSlider?: StyleRules; - MuiSnackbar?: StyleRules; - MuiSnackbarContent?: StyleRules; - MuiStep?: StyleRules; - MuiStepButton?: StyleRules; - MuiStepConnector?: StyleRules; - MuiStepContent?: StyleRules; - MuiStepIcon?: StyleRules; - MuiStepLabel?: StyleRules; - MuiStepper?: StyleRules; - MuiSvgIcon?: StyleRules; - MuiSwitch?: StyleRules; - MuiTab?: StyleRules; - MuiTable?: StyleRules; - MuiTableBody?: StyleRules; - MuiTableCell?: StyleRules; - MuiTableContainer?: StyleRules; - MuiTableFooter?: StyleRules; - MuiTableHead?: StyleRules; - MuiTablePagination?: StyleRules; - MuiTableRow?: StyleRules; - MuiTableSortLabel?: StyleRules; - MuiTabs?: StyleRules; - MuiTextField?: StyleRules; - MuiToolbar?: StyleRules; - MuiTooltip?: StyleRules; - MuiTouchRipple?: StyleRules; - MuiTypography?: StyleRules; -} diff --git a/packages/material-ui/src/styles/createMuiTheme.d.ts b/packages/material-ui/src/styles/createMuiTheme.d.ts index 30b61b3bffd782..ba23c8ef7b5fe1 100644 --- a/packages/material-ui/src/styles/createMuiTheme.d.ts +++ b/packages/material-ui/src/styles/createMuiTheme.d.ts @@ -8,7 +8,6 @@ import { Spacing, SpacingOptions } from './createSpacing'; import { Transitions, TransitionsOptions } from './transitions'; import { ZIndex, ZIndexOptions } from './zIndex'; import { Overrides } from './overrides'; -import { Additions } from './additions'; import { Variants } from './variants'; import { ComponentsProps } from './props'; @@ -16,9 +15,6 @@ export type Direction = 'ltr' | 'rtl'; export interface ThemeOptions { shape?: ShapeOptions; - additions?: Additions; - variants?: any; - variantsV2?: Variants; breakpoints?: BreakpointsOptions; direction?: Direction; mixins?: MixinsOptions; @@ -29,24 +25,24 @@ export interface ThemeOptions { spacing?: SpacingOptions; transitions?: TransitionsOptions; typography?: TypographyOptions | ((palette: Palette) => TypographyOptions); + variants?: Variants; zIndex?: ZIndexOptions; unstable_strictMode?: boolean; } export interface Theme { shape: Shape; - additions?: Additions; breakpoints: Breakpoints; direction: Direction; mixins: Mixins; overrides?: Overrides; palette: Palette; props?: ComponentsProps; - variants: any; shadows: Shadows; spacing: Spacing; transitions: Transitions; typography: Typography; + variants?: Variants; zIndex: ZIndex; unstable_strictMode?: boolean; } diff --git a/packages/material-ui/src/styles/createMuiTheme.js b/packages/material-ui/src/styles/createMuiTheme.js index 82e367f9467ab2..d1a68e3f83e03e 100644 --- a/packages/material-ui/src/styles/createMuiTheme.js +++ b/packages/material-ui/src/styles/createMuiTheme.js @@ -25,7 +25,6 @@ function createMuiTheme(options = {}, ...args) { let muiTheme = deepmerge( { - additions: {}, breakpoints, direction: 'ltr', mixins: createMixins(breakpoints, spacing, mixinsInput), diff --git a/packages/material-ui/src/styles/variants.d.ts b/packages/material-ui/src/styles/variants.d.ts index f99ebbff55e8d1..2663c2f06ba315 100644 --- a/packages/material-ui/src/styles/variants.d.ts +++ b/packages/material-ui/src/styles/variants.d.ts @@ -1,8 +1,17 @@ import { ComponentsPropsList } from './props'; +import { CSSProperties, CreateCSSProperties, PropsFunc } from './withStyles'; export type Variants = { [Name in keyof ComponentsPropsList]?: { - matcher: Partial, - styles: string; - } -}; \ No newline at end of file + matcher: Partial; + styles: // JSS property bag + | CSSProperties + // JSS property bag where values are based on props + | CreateCSSProperties> + // JSS property bag based on props + | PropsFunc< + Partial, + CreateCSSProperties> + >; + }[]; +}; From 2375c98695bc7c60d3b47d152f0a7efdbfbb1d57 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 6 Jul 2020 08:48:03 +0200 Subject: [PATCH 15/81] ts example updated --- .../pages/components/buttons/CustomVariantButtons.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/src/pages/components/buttons/CustomVariantButtons.tsx b/docs/src/pages/components/buttons/CustomVariantButtons.tsx index 737af2ec06ba9c..463b862f4a78c1 100644 --- a/docs/src/pages/components/buttons/CustomVariantButtons.tsx +++ b/docs/src/pages/components/buttons/CustomVariantButtons.tsx @@ -2,11 +2,12 @@ import React from 'react'; import { createMuiTheme, makeStyles, + Theme, ThemeProvider, } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; -const useStyles = makeStyles((theme) => ({ +const useStyles = makeStyles((theme: Theme) => ({ margin: { margin: theme.spacing(1), }, @@ -30,15 +31,15 @@ const theme = createMuiTheme({ }, { matcher: { size: 'xxlarge' }, - styles: { - fontSize: '50px', - }, + styles: (theme: Theme) => ({ + fontSize: theme.typography.pxToRem(20), + }), }, ], }, }); -export default function CustomizedButtons() { +export default function CustomVariantButtons() { const classes = useStyles(); return ( From c032672c9a7783fad4b376510fe272514bf173ab Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 6 Jul 2020 08:57:58 +0200 Subject: [PATCH 16/81] Update packages/material-ui-styles/src/withStyles/withStyles.js --- packages/material-ui-styles/src/withStyles/withStyles.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/material-ui-styles/src/withStyles/withStyles.js b/packages/material-ui-styles/src/withStyles/withStyles.js index d83ac4fc01b58e..e1d3db8982a075 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.js @@ -58,6 +58,7 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { // name and withTheme are invariant in the outer scope // eslint-disable-next-line react-hooks/rules-of-hooks theme = useTheme() || defaultTheme; + if (name) { more = getThemeProps({ theme, name, props: other }); } From 22d5f4a08887b087df4e8a2d9c48e70c79d63464 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 6 Jul 2020 08:58:21 +0200 Subject: [PATCH 17/81] Update packages/material-ui-styles/src/withStyles/withStyles.js --- packages/material-ui-styles/src/withStyles/withStyles.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/material-ui-styles/src/withStyles/withStyles.js b/packages/material-ui-styles/src/withStyles/withStyles.js index e1d3db8982a075..d83ac4fc01b58e 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.js @@ -58,7 +58,6 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { // name and withTheme are invariant in the outer scope // eslint-disable-next-line react-hooks/rules-of-hooks theme = useTheme() || defaultTheme; - if (name) { more = getThemeProps({ theme, name, props: other }); } From 3fcb966d158c5cf9edbd97748a6f94711be0b415 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 6 Jul 2020 08:59:27 +0200 Subject: [PATCH 18/81] reverted changes --- packages/material-ui-styles/src/withStyles/withStyles.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/material-ui-styles/src/withStyles/withStyles.js b/packages/material-ui-styles/src/withStyles/withStyles.js index d83ac4fc01b58e..bfccbf25074786 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.js @@ -48,8 +48,7 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { // The wrapper receives only user supplied props, which could be a subset of // the actual props Component might receive due to merging with defaultProps. // So copying it here would give us the same result in the wrapper as well. - const allProps = { ...Component.defaultProps, ...props }; - const classes = useStyles(allProps); + const classes = useStyles({ ...Component.defaultProps, ...props }); let theme; let more = other; @@ -58,6 +57,7 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { // name and withTheme are invariant in the outer scope // eslint-disable-next-line react-hooks/rules-of-hooks theme = useTheme() || defaultTheme; + if (name) { more = getThemeProps({ theme, name, props: other }); } From 212db32d485c2e4531b33dbbb3311cab09fe32e4 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 6 Jul 2020 10:43:37 +0200 Subject: [PATCH 19/81] Update packages/material-ui/src/styles/createMuiTheme.js --- packages/material-ui/src/styles/createMuiTheme.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/styles/createMuiTheme.js b/packages/material-ui/src/styles/createMuiTheme.js index d1a68e3f83e03e..211d140700f915 100644 --- a/packages/material-ui/src/styles/createMuiTheme.js +++ b/packages/material-ui/src/styles/createMuiTheme.js @@ -96,7 +96,7 @@ function createMuiTheme(options = {}, ...args) { }; traverse(muiTheme.overrides); - traverse(muiTheme.additions); + traverse(muiTheme.variants); } return muiTheme; From f92dbaab6bc457479b6c968d243bca084b9dcc2c Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 6 Jul 2020 11:51:06 +0200 Subject: [PATCH 20/81] tests fixes --- docs/pages/api-docs/button.md | 2 +- .../components/buttons/CustomVariantButtons.js | 6 +++--- .../components/buttons/CustomVariantButtons.tsx | 6 +++--- .../src/getStylesCreator/getStylesCreator.js | 17 ++++++++++------- packages/material-ui-utils/src/deepmerge.js | 3 +-- packages/material-ui/src/styles/variants.d.ts | 6 +++--- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/docs/pages/api-docs/button.md b/docs/pages/api-docs/button.md index 35c102f4902bc2..fd94f89f0e681c 100644 --- a/docs/pages/api-docs/button.md +++ b/docs/pages/api-docs/button.md @@ -30,7 +30,7 @@ The `MuiButton` name can be used for providing [default props](/customization/gl |:-----|:-----|:--------|:------------| | children | node | | The content of the button. | | classes | object | | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. | -| color | 'default'
| 'inherit'
| 'primary'
| 'secondary'
| string
| 'default' | The color of the component. It supports those theme colors that make sense for this component. | +| color | 'inherit'
| 'primary'
| 'secondary'
| string
| 'primary' | The color of the component. It supports those theme colors that make sense for this component. | | component | elementType | 'button' | The component used for the root node. Either a string to use a HTML element or a component. | | disabled | bool | false | If `true`, the button will be disabled. | | disableElevation | bool | false | If `true`, no elevation is used. | diff --git a/docs/src/pages/components/buttons/CustomVariantButtons.js b/docs/src/pages/components/buttons/CustomVariantButtons.js index 6d21ca85574aed..ae75c2efdfc8d5 100644 --- a/docs/src/pages/components/buttons/CustomVariantButtons.js +++ b/docs/src/pages/components/buttons/CustomVariantButtons.js @@ -30,9 +30,9 @@ const theme = createMuiTheme({ }, { matcher: { size: 'xxlarge' }, - styles: (theme) => ({ - fontSize: theme.typography.pxToRem(20), - }), + styles: { + fontSize: 20, + }, }, ], }, diff --git a/docs/src/pages/components/buttons/CustomVariantButtons.tsx b/docs/src/pages/components/buttons/CustomVariantButtons.tsx index 463b862f4a78c1..ec777c3d2d1fcb 100644 --- a/docs/src/pages/components/buttons/CustomVariantButtons.tsx +++ b/docs/src/pages/components/buttons/CustomVariantButtons.tsx @@ -31,9 +31,9 @@ const theme = createMuiTheme({ }, { matcher: { size: 'xxlarge' }, - styles: (theme: Theme) => ({ - fontSize: theme.typography.pxToRem(20), - }), + styles: { + fontSize: 20, + }, }, ], }, diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index cd933c92411516..7efc9e5a416513 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -5,13 +5,17 @@ const capitalize = (string) => { return string.charAt(0).toUpperCase() + string.slice(1); }; +const isEmpty = (string) => { + return string.length === 0; +} + const propsToClassKey = (matcher) => { let classKey = matcher.variant ? matcher.variant : ''; if (matcher.color) { - classKey += classKey.length === 0 ? matcher.color : capitalize(matcher.color); + classKey += isEmpty(classKey) ? matcher.color : capitalize(matcher.color); } if (matcher.size) { - classKey += (classKey.length === 0 ? 's' : 'S') + `ize${capitalize(matcher.size)}`; + classKey += `${(isEmpty(classKey) ? 'size' : 'Size')}${capitalize(matcher.size)}`; } return classKey; }; @@ -58,8 +62,8 @@ export default function getStylesCreator(stylesOrCreator) { return styles; } - const overrides = theme.overrides[name] || {}; - const variants = theme.variants[name] || []; + const overrides = theme.overrides && theme.overrides[name] || {}; + const variants = theme.variants && theme.variants[name] || []; const stylesWithOverrides = { ...styles }; Object.keys(overrides).forEach((key) => { @@ -77,11 +81,10 @@ export default function getStylesCreator(stylesOrCreator) { stylesWithOverrides[key] = deepmerge(stylesWithOverrides[key] || {}, overrides[key]); }); + variants.forEach((definition) => { const classKey = propsToClassKey(definition.matcher); - const styles = - typeof definition.styles === 'function' ? definition.styles(theme) : definition.styles; - stylesWithOverrides[classKey] = deepmerge(stylesWithOverrides[classKey] || {}, styles); + stylesWithOverrides[classKey] = deepmerge(stylesWithOverrides[classKey] || {}, definition.styles); }); return stylesWithOverrides; diff --git a/packages/material-ui-utils/src/deepmerge.js b/packages/material-ui-utils/src/deepmerge.js index 2bca86234b4669..052d38027bdc54 100644 --- a/packages/material-ui-utils/src/deepmerge.js +++ b/packages/material-ui-utils/src/deepmerge.js @@ -5,7 +5,6 @@ export function isPlainObject(item) { export default function deepmerge(target, source, options = { clone: true }) { const output = options.clone ? { ...target } : target; - // TODO: add merging of arrays if (isPlainObject(target) && isPlainObject(source)) { Object.keys(source).forEach((key) => { // Avoid prototype pollution @@ -15,7 +14,7 @@ export default function deepmerge(target, source, options = { clone: true }) { if (isPlainObject(source[key]) && key in target) { output[key] = deepmerge(target[key], source[key], options); - } else { + } else{ output[key] = source[key]; } }); diff --git a/packages/material-ui/src/styles/variants.d.ts b/packages/material-ui/src/styles/variants.d.ts index 2663c2f06ba315..7a30660b50c09f 100644 --- a/packages/material-ui/src/styles/variants.d.ts +++ b/packages/material-ui/src/styles/variants.d.ts @@ -1,8 +1,8 @@ import { ComponentsPropsList } from './props'; -import { CSSProperties, CreateCSSProperties, PropsFunc } from './withStyles'; +import { CSSProperties, CreateCSSProperties, PropsFunc } from '@material-ui/styles/withStyles'; export type Variants = { - [Name in keyof ComponentsPropsList]?: { + [Name in keyof ComponentsPropsList]?: Array<{ matcher: Partial; styles: // JSS property bag | CSSProperties @@ -13,5 +13,5 @@ export type Variants = { Partial, CreateCSSProperties> >; - }[]; + }>; }; From ce2369f4d057a9805cd15e789e6cc8ef3945510f Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 6 Jul 2020 12:01:11 +0200 Subject: [PATCH 21/81] prettier --- .../src/getStylesCreator/getStylesCreator.js | 13 ++++++++----- packages/material-ui-utils/src/deepmerge.js | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 7efc9e5a416513..d83e6a083ebea6 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -7,7 +7,7 @@ const capitalize = (string) => { const isEmpty = (string) => { return string.length === 0; -} +}; const propsToClassKey = (matcher) => { let classKey = matcher.variant ? matcher.variant : ''; @@ -15,7 +15,7 @@ const propsToClassKey = (matcher) => { classKey += isEmpty(classKey) ? matcher.color : capitalize(matcher.color); } if (matcher.size) { - classKey += `${(isEmpty(classKey) ? 'size' : 'Size')}${capitalize(matcher.size)}`; + classKey += `${isEmpty(classKey) ? 'size' : 'Size'}${capitalize(matcher.size)}`; } return classKey; }; @@ -62,8 +62,8 @@ export default function getStylesCreator(stylesOrCreator) { return styles; } - const overrides = theme.overrides && theme.overrides[name] || {}; - const variants = theme.variants && theme.variants[name] || []; + const overrides = (theme.overrides && theme.overrides[name]) || {}; + const variants = (theme.variants && theme.variants[name]) || []; const stylesWithOverrides = { ...styles }; Object.keys(overrides).forEach((key) => { @@ -84,7 +84,10 @@ export default function getStylesCreator(stylesOrCreator) { variants.forEach((definition) => { const classKey = propsToClassKey(definition.matcher); - stylesWithOverrides[classKey] = deepmerge(stylesWithOverrides[classKey] || {}, definition.styles); + stylesWithOverrides[classKey] = deepmerge( + stylesWithOverrides[classKey] || {}, + definition.styles, + ); }); return stylesWithOverrides; diff --git a/packages/material-ui-utils/src/deepmerge.js b/packages/material-ui-utils/src/deepmerge.js index 052d38027bdc54..3d6cf634730981 100644 --- a/packages/material-ui-utils/src/deepmerge.js +++ b/packages/material-ui-utils/src/deepmerge.js @@ -14,7 +14,7 @@ export default function deepmerge(target, source, options = { clone: true }) { if (isPlainObject(source[key]) && key in target) { output[key] = deepmerge(target[key], source[key], options); - } else{ + } else { output[key] = source[key]; } }); From 0e6733988b640b87432b102c89e3a59fab2ff9ba Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 7 Jul 2020 20:27:18 +0200 Subject: [PATCH 22/81] addressing comments --- docs/src/pages/components/buttons/buttons.md | 6 ---- .../components/GlobalThemeVariants.js} | 35 ++++++++++--------- .../components/GlobalThemeVariants.tsx} | 35 ++++++++++--------- .../customization/components/components.md | 34 ++++++++++++++++++ .../material-ui/src/styles/createMuiTheme.js | 1 - 5 files changed, 72 insertions(+), 39 deletions(-) rename docs/src/pages/{components/buttons/CustomVariantButtons.js => customization/components/GlobalThemeVariants.js} (66%) rename docs/src/pages/{components/buttons/CustomVariantButtons.tsx => customization/components/GlobalThemeVariants.tsx} (67%) diff --git a/docs/src/pages/components/buttons/buttons.md b/docs/src/pages/components/buttons/buttons.md index b31b52ab75514b..75094c7f3cd6ab 100644 --- a/docs/src/pages/components/buttons/buttons.md +++ b/docs/src/pages/components/buttons/buttons.md @@ -100,12 +100,6 @@ Here are some examples of customizing the component. You can learn more about th 🎨 If you are looking for inspiration, you can check [MUI Treasury's customization examples](https://mui-treasury.com/styles/button). -## Custom variants buttons - -Here are some examples of how you can add your custom variants to the component. - -{{"demo": "pages/components/buttons/CustomVariantButtons.js", "defaultCodeOpen": false}} - ## Loading buttons The loading buttons can show pending state and disable interactions. diff --git a/docs/src/pages/components/buttons/CustomVariantButtons.js b/docs/src/pages/customization/components/GlobalThemeVariants.js similarity index 66% rename from docs/src/pages/components/buttons/CustomVariantButtons.js rename to docs/src/pages/customization/components/GlobalThemeVariants.js index ae75c2efdfc8d5..339d5e627a853d 100644 --- a/docs/src/pages/components/buttons/CustomVariantButtons.js +++ b/docs/src/pages/customization/components/GlobalThemeVariants.js @@ -7,8 +7,10 @@ import { import Button from '@material-ui/core/Button'; const useStyles = makeStyles((theme) => ({ - margin: { - margin: theme.spacing(1), + root: { + '& > *': { + margin: theme.spacing(1), + } }, })); @@ -43,20 +45,21 @@ export default function CustomVariantButtons() { return ( - - - +
+ + + +
); } diff --git a/docs/src/pages/components/buttons/CustomVariantButtons.tsx b/docs/src/pages/customization/components/GlobalThemeVariants.tsx similarity index 67% rename from docs/src/pages/components/buttons/CustomVariantButtons.tsx rename to docs/src/pages/customization/components/GlobalThemeVariants.tsx index ec777c3d2d1fcb..cc5835a3fba8fe 100644 --- a/docs/src/pages/components/buttons/CustomVariantButtons.tsx +++ b/docs/src/pages/customization/components/GlobalThemeVariants.tsx @@ -8,8 +8,10 @@ import { import Button from '@material-ui/core/Button'; const useStyles = makeStyles((theme: Theme) => ({ - margin: { - margin: theme.spacing(1), + root: { + '& > *': { + margin: theme.spacing(1), + } }, })); @@ -44,20 +46,21 @@ export default function CustomVariantButtons() { return ( - - - +
+ + + +
); } diff --git a/docs/src/pages/customization/components/components.md b/docs/src/pages/customization/components/components.md index 3af44a3abc80b9..f50fb7950245a3 100644 --- a/docs/src/pages/customization/components/components.md +++ b/docs/src/pages/customization/components/components.md @@ -319,3 +319,37 @@ const theme = createMuiTheme({ ``` {{"demo": "pages/customization/components/GlobalThemeOverride.js"}} + +### Adding new theme variants + +You can take advantage of the `variants` key of the `theme` to potentially add new variants for the Material-UI components. + +```jsx +const theme = createMuiTheme({ + variants: { + MuiButton: [ + { + matcher: { variant: 'dashed' }, + styles: { + padding: '5px 15px', + border: '5px dashed grey', + }, + }, + { + matcher: { variant: 'dashed', color: 'teal' }, + styles: { + border: '5px dashed teal', + }, + }, + { + matcher: { size: 'xxlarge' }, + styles: { + fontSize: 20, + }, + }, + ], + }, +}); +``` + +{{"demo": "pages/customization/components/GlobalThemeVariants.js"}} diff --git a/packages/material-ui/src/styles/createMuiTheme.js b/packages/material-ui/src/styles/createMuiTheme.js index 211d140700f915..da1c8afcfbea45 100644 --- a/packages/material-ui/src/styles/createMuiTheme.js +++ b/packages/material-ui/src/styles/createMuiTheme.js @@ -96,7 +96,6 @@ function createMuiTheme(options = {}, ...args) { }; traverse(muiTheme.overrides); - traverse(muiTheme.variants); } return muiTheme; From ccaf13f9807253e7835f6033599870e20fcfd655 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 7 Jul 2020 20:35:23 +0200 Subject: [PATCH 23/81] prettier --- .../customization/components/GlobalThemeVariants.js | 12 +++--------- .../customization/components/GlobalThemeVariants.tsx | 12 +++--------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.js b/docs/src/pages/customization/components/GlobalThemeVariants.js index 339d5e627a853d..0c0ddc733f468e 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.js +++ b/docs/src/pages/customization/components/GlobalThemeVariants.js @@ -10,7 +10,7 @@ const useStyles = makeStyles((theme) => ({ root: { '& > *': { margin: theme.spacing(1), - } + }, }, })); @@ -46,17 +46,11 @@ export default function CustomVariantButtons() { return (
- + -
diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.tsx b/docs/src/pages/customization/components/GlobalThemeVariants.tsx index cc5835a3fba8fe..84f642b9a93b46 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.tsx +++ b/docs/src/pages/customization/components/GlobalThemeVariants.tsx @@ -11,7 +11,7 @@ const useStyles = makeStyles((theme: Theme) => ({ root: { '& > *': { margin: theme.spacing(1), - } + }, }, })); @@ -47,17 +47,11 @@ export default function CustomVariantButtons() { return (
- + -
From 070ffe035158f4ed5945453f101057975563a6d1 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 7 Jul 2020 21:26:03 +0200 Subject: [PATCH 24/81] replace relaxed typings with ts declare module --- .../components/GlobalThemeVariants.js | 6 +++--- .../components/GlobalThemeVariants.tsx | 18 +++++++++++++++--- packages/material-ui/src/Button/Button.d.ts | 16 +++++++++++++--- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.js b/docs/src/pages/customization/components/GlobalThemeVariants.js index 0c0ddc733f468e..00c921ab07b644 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.js +++ b/docs/src/pages/customization/components/GlobalThemeVariants.js @@ -31,7 +31,7 @@ const theme = createMuiTheme({ }, }, { - matcher: { size: 'xxlarge' }, + matcher: { size: 'xlarge' }, styles: { fontSize: 20, }, @@ -40,7 +40,7 @@ const theme = createMuiTheme({ }, }); -export default function CustomVariantButtons() { +export default function GlobalThemeVariants() { const classes = useStyles(); return ( @@ -50,7 +50,7 @@ export default function CustomVariantButtons() { - diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.tsx b/docs/src/pages/customization/components/GlobalThemeVariants.tsx index 84f642b9a93b46..748d376638e2aa 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.tsx +++ b/docs/src/pages/customization/components/GlobalThemeVariants.tsx @@ -7,6 +7,18 @@ import { } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; +declare module '@material-ui/core/Button/Button' { + interface ButtonPropsColorOverrides { + teal: true; + } + interface ButtonPropsVariantOverrides { + dashed: true; + } + interface ButtonPropsSizeOverrides { + xlarge: true; + } +} + const useStyles = makeStyles((theme: Theme) => ({ root: { '& > *': { @@ -32,7 +44,7 @@ const theme = createMuiTheme({ }, }, { - matcher: { size: 'xxlarge' }, + matcher: { size: 'xlarge' }, styles: { fontSize: 20, }, @@ -41,7 +53,7 @@ const theme = createMuiTheme({ }, }); -export default function CustomVariantButtons() { +export default function GlobalThemeVariants() { const classes = useStyles(); return ( @@ -51,7 +63,7 @@ export default function CustomVariantButtons() { - diff --git a/packages/material-ui/src/Button/Button.d.ts b/packages/material-ui/src/Button/Button.d.ts index ab68d90cdd9484..280d97632648c3 100644 --- a/packages/material-ui/src/Button/Button.d.ts +++ b/packages/material-ui/src/Button/Button.d.ts @@ -1,7 +1,17 @@ import { PropTypes } from '..'; +import { OverridableStringUnion } from '@material-ui/types'; import { ExtendButtonBase, ExtendButtonBaseTypeMap } from '../ButtonBase'; import { OverrideProps, OverridableComponent, OverridableTypeMap } from '../OverridableComponent'; +export interface ButtonPropsColorOverrides {} +export type ColorDefaults = Record<'inherit' | 'primary' | 'secondary', true>; + +export interface ButtonPropsVariantOverrides {} +export type VariantDefaults = Record<'text' | 'outlined' | 'contained', true>; + +export interface ButtonPropsSizeOverrides {} +export type SizeDefaults = Record<'small' | 'medium' | 'large', true>; + export type ButtonTypeMap< P = {}, D extends React.ElementType = 'button' @@ -14,7 +24,7 @@ export type ButtonTypeMap< /** * The color of the component. It supports those theme colors that make sense for this component. */ - color?: 'inherit' | 'primary' | 'secondary' | string; + color?: OverridableStringUnion; /** * If `true`, the button will be disabled. */ @@ -44,7 +54,7 @@ export type ButtonTypeMap< * The size of the button. * `small` is equivalent to the dense button styling. */ - size?: 'small' | 'medium' | 'large' | string; + size?: OverridableStringUnion; /** * Element placed before the children. */ @@ -52,7 +62,7 @@ export type ButtonTypeMap< /** * The variant to use. */ - variant?: 'text' | 'outlined' | 'contained' | string; + variant?: OverridableStringUnion; }; defaultComponent: D; classKey: ButtonClassKey; From a86137eaafcaf68294f35d16e49deb075e840d82 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 7 Jul 2020 21:33:20 +0200 Subject: [PATCH 25/81] improved description --- .../customization/components/components.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/src/pages/customization/components/components.md b/docs/src/pages/customization/components/components.md index f50fb7950245a3..3b13d2038e1943 100644 --- a/docs/src/pages/customization/components/components.md +++ b/docs/src/pages/customization/components/components.md @@ -341,15 +341,22 @@ const theme = createMuiTheme({ border: '5px dashed teal', }, }, - { - matcher: { size: 'xxlarge' }, - styles: { - fontSize: 20, - }, - }, ], }, }); ``` +If you are using typescript, you will need to specify your new variants/colors, using module augmentation. + +```tsx +declare module '@material-ui/core/Button/Button' { + interface ButtonPropsColorOverrides { + teal: true; + } + interface ButtonPropsVariantOverrides { + dashed: true; + } +} +``` + {{"demo": "pages/customization/components/GlobalThemeVariants.js"}} From 628e8fdf469df072d0040e2bc3afad3345e339e7 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 8 Jul 2020 09:14:05 +0200 Subject: [PATCH 26/81] themeMerge --- .../src/ThemeProvider/ThemeProvider.js | 24 +++++++++++++++++- .../src/ThemeProvider/ThemeProvider.test.js | 25 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js index 8fe98869589985..33cf36e79b6013 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js @@ -5,6 +5,28 @@ import ThemeContext from '../useTheme/ThemeContext'; import useTheme from '../useTheme'; import nested from './nested'; +export function isPlainObject(item) { + return item && typeof item === 'object' && item.constructor === Object; +} + +export function mergeThemes(target, source, options = { clone: true }) { + const output = options.clone ? { ...target } : target; + + if (isPlainObject(target) && isPlainObject(source)) { + Object.keys(source).forEach((key) => { + if (isPlainObject(source[key]) && key in target) { + output[key] = mergeThemes(target[key], source[key], options); + } else if(Array.isArray(source[key]) && key in target && Array.isArray(target[key]) && key.substring(0, 3) === 'Mui') { + output[key] = [...target[key], ...source[key]]; + } else { + output[key] = source[key]; + } + }); + } + + return output; +} + // To support composition of theme. function mergeOuterLocalTheme(outerTheme, localTheme) { if (typeof localTheme === 'function') { @@ -24,7 +46,7 @@ function mergeOuterLocalTheme(outerTheme, localTheme) { return mergedTheme; } - return { ...outerTheme, ...localTheme }; + return mergeThemes(outerTheme, localTheme); } /** diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js index 46238825dfaf8d..c4d6958aad1fdc 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js @@ -49,6 +49,31 @@ describe('ThemeProvider', () => { expect(text()).to.equal('foobar'); }); + it('should spread variant arrays when merging themes', () => { + const ref = React.createRef(); + const text = () => ref.current.textContent; + const outerVariants = [ { matcher: { variant: 'red'}, styles: { color: 'red'}} ]; + const innerVariants = [ { matcher: { variant: 'blue'}, styles: { color: 'blue'}} ] + function Test() { + const theme = useTheme(); + + return ( + + {JSON.stringify(theme.variants.MuiButton)} + + ); + } + + render( + + + + + , + ); + expect(text()).to.equal(JSON.stringify([ ...outerVariants, ...innerVariants])); + }); + it('should memoize the merged output', () => { const themes = []; From 132c930d1ccbad76808b7cdab475bda401019c68 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 8 Jul 2020 10:01:49 +0200 Subject: [PATCH 27/81] prettier --- .../src/ThemeProvider/ThemeProvider.js | 7 ++++++- .../src/ThemeProvider/ThemeProvider.test.js | 16 ++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js index 33cf36e79b6013..b86cc5778b8569 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js @@ -16,7 +16,12 @@ export function mergeThemes(target, source, options = { clone: true }) { Object.keys(source).forEach((key) => { if (isPlainObject(source[key]) && key in target) { output[key] = mergeThemes(target[key], source[key], options); - } else if(Array.isArray(source[key]) && key in target && Array.isArray(target[key]) && key.substring(0, 3) === 'Mui') { + } else if ( + Array.isArray(source[key]) && + key in target && + Array.isArray(target[key]) && + key.substring(0, 3) === 'Mui' + ) { output[key] = [...target[key], ...source[key]]; } else { output[key] = source[key]; diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js index c4d6958aad1fdc..3ae8c668889469 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js @@ -52,26 +52,22 @@ describe('ThemeProvider', () => { it('should spread variant arrays when merging themes', () => { const ref = React.createRef(); const text = () => ref.current.textContent; - const outerVariants = [ { matcher: { variant: 'red'}, styles: { color: 'red'}} ]; - const innerVariants = [ { matcher: { variant: 'blue'}, styles: { color: 'blue'}} ] + const outerVariants = [{ matcher: { variant: 'red' }, styles: { color: 'red' } }]; + const innerVariants = [{ matcher: { variant: 'blue' }, styles: { color: 'blue' } }]; function Test() { const theme = useTheme(); - return ( - - {JSON.stringify(theme.variants.MuiButton)} - - ); + return {JSON.stringify(theme.variants.MuiButton)}; } render( - - + + , ); - expect(text()).to.equal(JSON.stringify([ ...outerVariants, ...innerVariants])); + expect(text()).to.equal(JSON.stringify([...outerVariants, ...innerVariants])); }); it('should memoize the merged output', () => { From 5036d2de606b61e0e9f2fdeaf180b8110e8db939 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 10 Jul 2020 06:30:00 +0200 Subject: [PATCH 28/81] extract capitalize in utils --- .../src/getStylesCreator/getStylesCreator.js | 23 ++++++++++--------- packages/material-ui-utils/src/capitalize.js | 12 ++++++++++ .../src}/capitalize.test.js | 0 packages/material-ui-utils/src/index.js | 1 + packages/material-ui/src/utils/capitalize.js | 14 ++--------- 5 files changed, 27 insertions(+), 23 deletions(-) create mode 100644 packages/material-ui-utils/src/capitalize.js rename packages/{material-ui/src/utils => material-ui-utils/src}/capitalize.test.js (100%) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index d83e6a083ebea6..2c40ebef678874 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -1,22 +1,23 @@ -import { deepmerge } from '@material-ui/utils'; +import { deepmerge, capitalize } from '@material-ui/utils'; import noopTheme from './noopTheme'; -const capitalize = (string) => { - return string.charAt(0).toUpperCase() + string.slice(1); -}; - const isEmpty = (string) => { return string.length === 0; }; const propsToClassKey = (matcher) => { + const { variant, ...rest } = matcher; + let classKey = matcher.variant ? matcher.variant : ''; - if (matcher.color) { - classKey += isEmpty(classKey) ? matcher.color : capitalize(matcher.color); - } - if (matcher.size) { - classKey += `${isEmpty(classKey) ? 'size' : 'Size'}${capitalize(matcher.size)}`; - } + + Object.keys(rest).sort().forEach(key => { + if(key === 'color') { + classKey += isEmpty(classKey) ? matcher.color : capitalize(matcher.color); + } else { + classKey += `${isEmpty(classKey) ? key : capitalize}${capitalize(matcher.size)}`; + } + }); + return classKey; }; diff --git a/packages/material-ui-utils/src/capitalize.js b/packages/material-ui-utils/src/capitalize.js new file mode 100644 index 00000000000000..4c87d3020595a1 --- /dev/null +++ b/packages/material-ui-utils/src/capitalize.js @@ -0,0 +1,12 @@ +import MuiError from '@material-ui/utils/macros/MuiError.macro'; +// It should to be noted that this function isn't equivalent to `text-transform: capitalize`. +// +// A strict capitalization should uppercase the first letter of each word a the sentence. +// We only handle the first word. +export default function capitalize(string) { + if (typeof string !== 'string') { + throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); + } + + return string.charAt(0).toUpperCase() + string.slice(1); +} diff --git a/packages/material-ui/src/utils/capitalize.test.js b/packages/material-ui-utils/src/capitalize.test.js similarity index 100% rename from packages/material-ui/src/utils/capitalize.test.js rename to packages/material-ui-utils/src/capitalize.test.js diff --git a/packages/material-ui-utils/src/index.js b/packages/material-ui-utils/src/index.js index 03b77400974236..7ba3aa8e760fa3 100644 --- a/packages/material-ui-utils/src/index.js +++ b/packages/material-ui-utils/src/index.js @@ -1,3 +1,4 @@ +export { default as capitalize } from './capitalize'; export { default as chainPropTypes } from './chainPropTypes'; export { default as deepmerge } from './deepmerge'; export { default as elementAcceptingRef } from './elementAcceptingRef'; diff --git a/packages/material-ui/src/utils/capitalize.js b/packages/material-ui/src/utils/capitalize.js index 4c87d3020595a1..64f470b79f7e86 100644 --- a/packages/material-ui/src/utils/capitalize.js +++ b/packages/material-ui/src/utils/capitalize.js @@ -1,12 +1,2 @@ -import MuiError from '@material-ui/utils/macros/MuiError.macro'; -// It should to be noted that this function isn't equivalent to `text-transform: capitalize`. -// -// A strict capitalization should uppercase the first letter of each word a the sentence. -// We only handle the first word. -export default function capitalize(string) { - if (typeof string !== 'string') { - throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); - } - - return string.charAt(0).toUpperCase() + string.slice(1); -} +import { capitalize } from '@material-ui/utils' +export default capitalize; From 5e7912630967641a32e3d3b480d9646bc2202207 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 10 Jul 2020 06:59:21 +0200 Subject: [PATCH 29/81] removed mergeThemes --- .../src/ThemeProvider/ThemeProvider.js | 31 ++----------------- .../src/getStylesCreator/getStylesCreator.js | 18 ++++++----- packages/material-ui-utils/src/deepmerge.js | 14 ++++++++- packages/material-ui/src/utils/capitalize.js | 3 +- 4 files changed, 27 insertions(+), 39 deletions(-) diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js index b86cc5778b8569..505e74533f4336 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js @@ -1,37 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { exactProp } from '@material-ui/utils'; +import { exactProp, deepmerge } from '@material-ui/utils'; import ThemeContext from '../useTheme/ThemeContext'; import useTheme from '../useTheme'; import nested from './nested'; -export function isPlainObject(item) { - return item && typeof item === 'object' && item.constructor === Object; -} - -export function mergeThemes(target, source, options = { clone: true }) { - const output = options.clone ? { ...target } : target; - - if (isPlainObject(target) && isPlainObject(source)) { - Object.keys(source).forEach((key) => { - if (isPlainObject(source[key]) && key in target) { - output[key] = mergeThemes(target[key], source[key], options); - } else if ( - Array.isArray(source[key]) && - key in target && - Array.isArray(target[key]) && - key.substring(0, 3) === 'Mui' - ) { - output[key] = [...target[key], ...source[key]]; - } else { - output[key] = source[key]; - } - }); - } - - return output; -} - // To support composition of theme. function mergeOuterLocalTheme(outerTheme, localTheme) { if (typeof localTheme === 'function') { @@ -51,7 +24,7 @@ function mergeOuterLocalTheme(outerTheme, localTheme) { return mergedTheme; } - return mergeThemes(outerTheme, localTheme); + return deepmerge(outerTheme, localTheme); } /** diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 2c40ebef678874..9cb1989e0ed2e3 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -10,14 +10,16 @@ const propsToClassKey = (matcher) => { let classKey = matcher.variant ? matcher.variant : ''; - Object.keys(rest).sort().forEach(key => { - if(key === 'color') { - classKey += isEmpty(classKey) ? matcher.color : capitalize(matcher.color); - } else { - classKey += `${isEmpty(classKey) ? key : capitalize}${capitalize(matcher.size)}`; - } - }); - + Object.keys(rest) + .sort() + .forEach((key) => { + if (key === 'color') { + classKey += isEmpty(classKey) ? matcher.color : capitalize(matcher.color); + } else { + classKey += `${isEmpty(classKey) ? key : capitalize}${capitalize(matcher.size)}`; + } + }); + return classKey; }; diff --git a/packages/material-ui-utils/src/deepmerge.js b/packages/material-ui-utils/src/deepmerge.js index 3d6cf634730981..5f0c6de0a78e42 100644 --- a/packages/material-ui-utils/src/deepmerge.js +++ b/packages/material-ui-utils/src/deepmerge.js @@ -2,7 +2,11 @@ export function isPlainObject(item) { return item && typeof item === 'object' && item.constructor === Object; } -export default function deepmerge(target, source, options = { clone: true }) { +export default function deepmerge( + target, + source, + options = { clone: true, mergeVariantsArray: true }, +) { const output = options.clone ? { ...target } : target; if (isPlainObject(target) && isPlainObject(source)) { @@ -14,6 +18,14 @@ export default function deepmerge(target, source, options = { clone: true }) { if (isPlainObject(source[key]) && key in target) { output[key] = deepmerge(target[key], source[key], options); + } else if ( + options.mergeVariantsArray && + Array.isArray(source[key]) && + key in target && + Array.isArray(target[key]) && + key.substring(0, 3) === 'Mui' + ) { + output[key] = [...target[key], ...source[key]]; } else { output[key] = source[key]; } diff --git a/packages/material-ui/src/utils/capitalize.js b/packages/material-ui/src/utils/capitalize.js index 64f470b79f7e86..0ff91901fa1280 100644 --- a/packages/material-ui/src/utils/capitalize.js +++ b/packages/material-ui/src/utils/capitalize.js @@ -1,2 +1,3 @@ -import { capitalize } from '@material-ui/utils' +import { capitalize } from '@material-ui/utils'; + export default capitalize; From fa883ea31955e7d024807682f9cdf47ff773d345 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 10 Jul 2020 07:02:44 +0200 Subject: [PATCH 30/81] fix --- .../material-ui-styles/src/getStylesCreator/getStylesCreator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 9cb1989e0ed2e3..72aea7aad23ce5 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -16,7 +16,7 @@ const propsToClassKey = (matcher) => { if (key === 'color') { classKey += isEmpty(classKey) ? matcher.color : capitalize(matcher.color); } else { - classKey += `${isEmpty(classKey) ? key : capitalize}${capitalize(matcher.size)}`; + classKey += `${isEmpty(classKey) ? key : capitalize(key)}${capitalize(matcher.size)}`; } }); From 0ab15a61d9c0b3ae21253d330df0fddcdf478d95 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 10 Jul 2020 07:03:41 +0200 Subject: [PATCH 31/81] fixes --- .../src/getStylesCreator/getStylesCreator.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 72aea7aad23ce5..f0b7ee1c3c861b 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -14,9 +14,9 @@ const propsToClassKey = (matcher) => { .sort() .forEach((key) => { if (key === 'color') { - classKey += isEmpty(classKey) ? matcher.color : capitalize(matcher.color); + classKey += isEmpty(classKey) ? matcher[key] : capitalize(matcher[key]); } else { - classKey += `${isEmpty(classKey) ? key : capitalize(key)}${capitalize(matcher.size)}`; + classKey += `${isEmpty(classKey) ? key : capitalize(key)}${capitalize(matcher[key])}`; } }); From fed904bc4fa675e6df4bb1edf1d309fd932e76c2 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 10 Jul 2020 07:24:08 +0200 Subject: [PATCH 32/81] break circular dependency --- packages/material-ui-utils/src/capitalize.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/capitalize.js b/packages/material-ui-utils/src/capitalize.js index 4c87d3020595a1..ce5846c529b6a3 100644 --- a/packages/material-ui-utils/src/capitalize.js +++ b/packages/material-ui-utils/src/capitalize.js @@ -1,4 +1,4 @@ -import MuiError from '@material-ui/utils/macros/MuiError.macro'; +import MuiError from '../macros/MuiError.macro'; // It should to be noted that this function isn't equivalent to `text-transform: capitalize`. // // A strict capitalization should uppercase the first letter of each word a the sentence. From 9fcc43160328767f0c64ec6dc3ca4e5358ba77d9 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 10 Jul 2020 17:47:48 +0200 Subject: [PATCH 33/81] restricted to variables --- .../components/GlobalThemeVariants.js | 20 +++++--------- .../components/GlobalThemeVariants.tsx | 26 +++++-------------- .../customization/components/components.md | 9 +++---- 3 files changed, 15 insertions(+), 40 deletions(-) diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.js b/docs/src/pages/customization/components/GlobalThemeVariants.js index 00c921ab07b644..516900ecc03bb9 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.js +++ b/docs/src/pages/customization/components/GlobalThemeVariants.js @@ -5,6 +5,7 @@ import { ThemeProvider, } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; +import { blue, red } from '@material-ui/core/colors'; const useStyles = makeStyles((theme) => ({ root: { @@ -21,19 +22,13 @@ const theme = createMuiTheme({ matcher: { variant: 'dashed' }, styles: { padding: '5px 15px', - border: '5px dashed grey', + border: `5px dashed ${blue[500]}`, }, }, { - matcher: { variant: 'dashed', color: 'teal' }, + matcher: { variant: 'dashed', color: 'secondary' }, styles: { - border: '5px dashed teal', - }, - }, - { - matcher: { size: 'xlarge' }, - styles: { - fontSize: 20, + border: `5px dashed ${red[500]}`, }, }, ], @@ -47,11 +42,8 @@ export default function GlobalThemeVariants() {
- -
diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.tsx b/docs/src/pages/customization/components/GlobalThemeVariants.tsx index 748d376638e2aa..e3e581b6051541 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.tsx +++ b/docs/src/pages/customization/components/GlobalThemeVariants.tsx @@ -6,17 +6,12 @@ import { ThemeProvider, } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; +import { blue, red } from '@material-ui/core/colors'; declare module '@material-ui/core/Button/Button' { - interface ButtonPropsColorOverrides { - teal: true; - } interface ButtonPropsVariantOverrides { dashed: true; } - interface ButtonPropsSizeOverrides { - xlarge: true; - } } const useStyles = makeStyles((theme: Theme) => ({ @@ -34,19 +29,13 @@ const theme = createMuiTheme({ matcher: { variant: 'dashed' }, styles: { padding: '5px 15px', - border: '5px dashed grey', + border: `5px dashed ${blue[500]}`, }, }, { - matcher: { variant: 'dashed', color: 'teal' }, + matcher: { variant: 'dashed', color: 'secondary' }, styles: { - border: '5px dashed teal', - }, - }, - { - matcher: { size: 'xlarge' }, - styles: { - fontSize: 20, + border: `5px dashed ${red[500]}`, }, }, ], @@ -60,11 +49,8 @@ export default function GlobalThemeVariants() {
- -
diff --git a/docs/src/pages/customization/components/components.md b/docs/src/pages/customization/components/components.md index 3b13d2038e1943..9e244712cef1ad 100644 --- a/docs/src/pages/customization/components/components.md +++ b/docs/src/pages/customization/components/components.md @@ -332,13 +332,13 @@ const theme = createMuiTheme({ matcher: { variant: 'dashed' }, styles: { padding: '5px 15px', - border: '5px dashed grey', + border: `5px dashed grey${blue[500]}`, }, }, { - matcher: { variant: 'dashed', color: 'teal' }, + matcher: { variant: 'dashed', color: 'secondary' }, styles: { - border: '5px dashed teal', + border: `5px dashed ${red[500]}`, }, }, ], @@ -350,9 +350,6 @@ If you are using typescript, you will need to specify your new variants/colors, ```tsx declare module '@material-ui/core/Button/Button' { - interface ButtonPropsColorOverrides { - teal: true; - } interface ButtonPropsVariantOverrides { dashed: true; } From 313f8bf9ce4fc071d03ae0118060995f197e015f Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 10 Jul 2020 17:53:16 +0200 Subject: [PATCH 34/81] reverted some changes --- packages/material-ui/src/Button/Button.d.ts | 10 ++-------- packages/material-ui/src/Button/Button.js | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/packages/material-ui/src/Button/Button.d.ts b/packages/material-ui/src/Button/Button.d.ts index 280d97632648c3..5078f3ee355e7b 100644 --- a/packages/material-ui/src/Button/Button.d.ts +++ b/packages/material-ui/src/Button/Button.d.ts @@ -3,15 +3,9 @@ import { OverridableStringUnion } from '@material-ui/types'; import { ExtendButtonBase, ExtendButtonBaseTypeMap } from '../ButtonBase'; import { OverrideProps, OverridableComponent, OverridableTypeMap } from '../OverridableComponent'; -export interface ButtonPropsColorOverrides {} -export type ColorDefaults = Record<'inherit' | 'primary' | 'secondary', true>; - export interface ButtonPropsVariantOverrides {} export type VariantDefaults = Record<'text' | 'outlined' | 'contained', true>; -export interface ButtonPropsSizeOverrides {} -export type SizeDefaults = Record<'small' | 'medium' | 'large', true>; - export type ButtonTypeMap< P = {}, D extends React.ElementType = 'button' @@ -24,7 +18,7 @@ export type ButtonTypeMap< /** * The color of the component. It supports those theme colors that make sense for this component. */ - color?: OverridableStringUnion; + color?: 'inherit' | 'primary' | 'secondary'; /** * If `true`, the button will be disabled. */ @@ -54,7 +48,7 @@ export type ButtonTypeMap< * The size of the button. * `small` is equivalent to the dense button styling. */ - size?: OverridableStringUnion; + size?: 'small' | 'medium' | 'large'; /** * Element placed before the children. */ diff --git a/packages/material-ui/src/Button/Button.js b/packages/material-ui/src/Button/Button.js index 51d19615aa13f7..3e7f0506995509 100644 --- a/packages/material-ui/src/Button/Button.js +++ b/packages/material-ui/src/Button/Button.js @@ -350,10 +350,7 @@ Button.propTypes = { /** * The color of the component. It supports those theme colors that make sense for this component. */ - color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ - PropTypes.oneOf(['inherit', 'primary', 'secondary']), - PropTypes.string, - ]), + color: PropTypes.oneOf(['inherit', 'primary', 'secondary']), /** * The component used for the root node. * Either a string to use a HTML element or a component. @@ -399,10 +396,7 @@ Button.propTypes = { * The size of the button. * `small` is equivalent to the dense button styling. */ - size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ - PropTypes.oneOf(['large', 'medium', 'small']), - PropTypes.string, - ]), + size: PropTypes.oneOf(['large', 'medium', 'small']), /** * Element placed before the children. */ From 60787abaecf4c6343b91c0941fd54554bb1ab2d5 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 10 Jul 2020 18:14:28 +0200 Subject: [PATCH 35/81] docs:api --- docs/pages/api-docs/button.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/api-docs/button.md b/docs/pages/api-docs/button.md index fd94f89f0e681c..53ef1362ffbfe5 100644 --- a/docs/pages/api-docs/button.md +++ b/docs/pages/api-docs/button.md @@ -30,7 +30,7 @@ The `MuiButton` name can be used for providing [default props](/customization/gl |:-----|:-----|:--------|:------------| | children | node | | The content of the button. | | classes | object | | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. | -| color | 'inherit'
| 'primary'
| 'secondary'
| string
| 'primary' | The color of the component. It supports those theme colors that make sense for this component. | +| color | 'inherit'
| 'primary'
| 'secondary'
| 'primary' | The color of the component. It supports those theme colors that make sense for this component. | | component | elementType | 'button' | The component used for the root node. Either a string to use a HTML element or a component. | | disabled | bool | false | If `true`, the button will be disabled. | | disableElevation | bool | false | If `true`, no elevation is used. | @@ -39,7 +39,7 @@ The `MuiButton` name can be used for providing [default props](/customization/gl | endIcon | node | | Element placed after the children. | | fullWidth | bool | false | If `true`, the button will take up the full width of its container. | | href | string | | The URL to link to when the button is clicked. If defined, an `a` element will be used as the root node. | -| size | 'large'
| 'medium'
| 'small'
| string
| 'medium' | The size of the button. `small` is equivalent to the dense button styling. | +| size | 'large'
| 'medium'
| 'small'
| 'medium' | The size of the button. `small` is equivalent to the dense button styling. | | startIcon | node | | Element placed before the children. | | variant | 'contained'
| 'outlined'
| 'text'
| string
| 'text' | The variant to use. | From f04ccb4b05b98b64964bc24a93fb6a3736207a91 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 10 Jul 2020 20:30:16 +0200 Subject: [PATCH 36/81] removed new capitalize method --- .../src/getStylesCreator/getStylesCreator.js | 12 +++++++++++- packages/material-ui-utils/src/capitalize.js | 12 ------------ packages/material-ui-utils/src/index.js | 1 - packages/material-ui/src/utils/capitalize.js | 13 +++++++++++-- .../src/utils}/capitalize.test.js | 0 5 files changed, 22 insertions(+), 16 deletions(-) delete mode 100644 packages/material-ui-utils/src/capitalize.js rename packages/{material-ui-utils/src => material-ui/src/utils}/capitalize.test.js (100%) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index f0b7ee1c3c861b..5ba5233fb29bba 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -1,6 +1,16 @@ -import { deepmerge, capitalize } from '@material-ui/utils'; +import { deepmerge } from '@material-ui/utils'; +import MuiError from '@material-ui/utils/macros/MuiError.macro'; import noopTheme from './noopTheme'; +// TODO: remove this once the capiitalize is moved to the @material-ui/utils package +export default function capitalize(string) { + if (typeof string !== 'string') { + throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); + } + + return string.charAt(0).toUpperCase() + string.slice(1); +} + const isEmpty = (string) => { return string.length === 0; }; diff --git a/packages/material-ui-utils/src/capitalize.js b/packages/material-ui-utils/src/capitalize.js deleted file mode 100644 index ce5846c529b6a3..00000000000000 --- a/packages/material-ui-utils/src/capitalize.js +++ /dev/null @@ -1,12 +0,0 @@ -import MuiError from '../macros/MuiError.macro'; -// It should to be noted that this function isn't equivalent to `text-transform: capitalize`. -// -// A strict capitalization should uppercase the first letter of each word a the sentence. -// We only handle the first word. -export default function capitalize(string) { - if (typeof string !== 'string') { - throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); - } - - return string.charAt(0).toUpperCase() + string.slice(1); -} diff --git a/packages/material-ui-utils/src/index.js b/packages/material-ui-utils/src/index.js index 7ba3aa8e760fa3..03b77400974236 100644 --- a/packages/material-ui-utils/src/index.js +++ b/packages/material-ui-utils/src/index.js @@ -1,4 +1,3 @@ -export { default as capitalize } from './capitalize'; export { default as chainPropTypes } from './chainPropTypes'; export { default as deepmerge } from './deepmerge'; export { default as elementAcceptingRef } from './elementAcceptingRef'; diff --git a/packages/material-ui/src/utils/capitalize.js b/packages/material-ui/src/utils/capitalize.js index 0ff91901fa1280..4c87d3020595a1 100644 --- a/packages/material-ui/src/utils/capitalize.js +++ b/packages/material-ui/src/utils/capitalize.js @@ -1,3 +1,12 @@ -import { capitalize } from '@material-ui/utils'; +import MuiError from '@material-ui/utils/macros/MuiError.macro'; +// It should to be noted that this function isn't equivalent to `text-transform: capitalize`. +// +// A strict capitalization should uppercase the first letter of each word a the sentence. +// We only handle the first word. +export default function capitalize(string) { + if (typeof string !== 'string') { + throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); + } -export default capitalize; + return string.charAt(0).toUpperCase() + string.slice(1); +} diff --git a/packages/material-ui-utils/src/capitalize.test.js b/packages/material-ui/src/utils/capitalize.test.js similarity index 100% rename from packages/material-ui-utils/src/capitalize.test.js rename to packages/material-ui/src/utils/capitalize.test.js From 1b81481cb872107fe3f90b9168a685980865082d Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 11 Jul 2020 07:26:23 +0200 Subject: [PATCH 37/81] removed default exprot --- .../material-ui-styles/src/getStylesCreator/getStylesCreator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 5ba5233fb29bba..39fff6ac6ef669 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -3,7 +3,7 @@ import MuiError from '@material-ui/utils/macros/MuiError.macro'; import noopTheme from './noopTheme'; // TODO: remove this once the capiitalize is moved to the @material-ui/utils package -export default function capitalize(string) { +export function capitalize(string) { if (typeof string !== 'string') { throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); } From 7f12e681994a4d0a254b05cb4bbe5679715ffce3 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 11 Jul 2020 07:55:38 +0200 Subject: [PATCH 38/81] revert some changes, improved example --- .../components/GlobalThemeVariants.js | 7 +++---- .../components/GlobalThemeVariants.tsx | 7 +++---- .../src/ThemeProvider/ThemeProvider.js | 4 ++-- .../src/ThemeProvider/ThemeProvider.test.js | 21 ------------------- packages/material-ui-utils/src/deepmerge.js | 14 +------------ 5 files changed, 9 insertions(+), 44 deletions(-) diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.js b/docs/src/pages/customization/components/GlobalThemeVariants.js index 516900ecc03bb9..2b7d15de1909f2 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.js +++ b/docs/src/pages/customization/components/GlobalThemeVariants.js @@ -5,7 +5,6 @@ import { ThemeProvider, } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; -import { blue, red } from '@material-ui/core/colors'; const useStyles = makeStyles((theme) => ({ root: { @@ -15,20 +14,20 @@ const useStyles = makeStyles((theme) => ({ }, })); -const theme = createMuiTheme({ +const theme = outerTheme => createMuiTheme({ variants: { MuiButton: [ { matcher: { variant: 'dashed' }, styles: { padding: '5px 15px', - border: `5px dashed ${blue[500]}`, + border: `5px dashed ${outerTheme.palette.primary.main}`, }, }, { matcher: { variant: 'dashed', color: 'secondary' }, styles: { - border: `5px dashed ${red[500]}`, + border: `5px dashed ${outerTheme.palette.secondary.main}`, }, }, ], diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.tsx b/docs/src/pages/customization/components/GlobalThemeVariants.tsx index e3e581b6051541..e24b1e0a867aae 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.tsx +++ b/docs/src/pages/customization/components/GlobalThemeVariants.tsx @@ -6,7 +6,6 @@ import { ThemeProvider, } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; -import { blue, red } from '@material-ui/core/colors'; declare module '@material-ui/core/Button/Button' { interface ButtonPropsVariantOverrides { @@ -22,20 +21,20 @@ const useStyles = makeStyles((theme: Theme) => ({ }, })); -const theme = createMuiTheme({ +const theme = (outerTheme: Theme) => createMuiTheme({ variants: { MuiButton: [ { matcher: { variant: 'dashed' }, styles: { padding: '5px 15px', - border: `5px dashed ${blue[500]}`, + border: `5px dashed ${outerTheme.palette.primary.main}`, }, }, { matcher: { variant: 'dashed', color: 'secondary' }, styles: { - border: `5px dashed ${red[500]}`, + border: `5px dashed ${outerTheme.palette.secondary.main}`, }, }, ], diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js index 505e74533f4336..8fe98869589985 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { exactProp, deepmerge } from '@material-ui/utils'; +import { exactProp } from '@material-ui/utils'; import ThemeContext from '../useTheme/ThemeContext'; import useTheme from '../useTheme'; import nested from './nested'; @@ -24,7 +24,7 @@ function mergeOuterLocalTheme(outerTheme, localTheme) { return mergedTheme; } - return deepmerge(outerTheme, localTheme); + return { ...outerTheme, ...localTheme }; } /** diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js index 3ae8c668889469..46238825dfaf8d 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js @@ -49,27 +49,6 @@ describe('ThemeProvider', () => { expect(text()).to.equal('foobar'); }); - it('should spread variant arrays when merging themes', () => { - const ref = React.createRef(); - const text = () => ref.current.textContent; - const outerVariants = [{ matcher: { variant: 'red' }, styles: { color: 'red' } }]; - const innerVariants = [{ matcher: { variant: 'blue' }, styles: { color: 'blue' } }]; - function Test() { - const theme = useTheme(); - - return {JSON.stringify(theme.variants.MuiButton)}; - } - - render( - - - - - , - ); - expect(text()).to.equal(JSON.stringify([...outerVariants, ...innerVariants])); - }); - it('should memoize the merged output', () => { const themes = []; diff --git a/packages/material-ui-utils/src/deepmerge.js b/packages/material-ui-utils/src/deepmerge.js index 5f0c6de0a78e42..3d6cf634730981 100644 --- a/packages/material-ui-utils/src/deepmerge.js +++ b/packages/material-ui-utils/src/deepmerge.js @@ -2,11 +2,7 @@ export function isPlainObject(item) { return item && typeof item === 'object' && item.constructor === Object; } -export default function deepmerge( - target, - source, - options = { clone: true, mergeVariantsArray: true }, -) { +export default function deepmerge(target, source, options = { clone: true }) { const output = options.clone ? { ...target } : target; if (isPlainObject(target) && isPlainObject(source)) { @@ -18,14 +14,6 @@ export default function deepmerge( if (isPlainObject(source[key]) && key in target) { output[key] = deepmerge(target[key], source[key], options); - } else if ( - options.mergeVariantsArray && - Array.isArray(source[key]) && - key in target && - Array.isArray(target[key]) && - key.substring(0, 3) === 'Mui' - ) { - output[key] = [...target[key], ...source[key]]; } else { output[key] = source[key]; } From e1c2d6d1da11791f84cb5c906af33877e13f09ae Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 11 Jul 2020 07:56:40 +0200 Subject: [PATCH 39/81] prettier --- .../components/GlobalThemeVariants.js | 35 ++++++++++--------- .../components/GlobalThemeVariants.tsx | 35 ++++++++++--------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.js b/docs/src/pages/customization/components/GlobalThemeVariants.js index 2b7d15de1909f2..ca90092dd01373 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.js +++ b/docs/src/pages/customization/components/GlobalThemeVariants.js @@ -14,25 +14,26 @@ const useStyles = makeStyles((theme) => ({ }, })); -const theme = outerTheme => createMuiTheme({ - variants: { - MuiButton: [ - { - matcher: { variant: 'dashed' }, - styles: { - padding: '5px 15px', - border: `5px dashed ${outerTheme.palette.primary.main}`, +const theme = (outerTheme) => + createMuiTheme({ + variants: { + MuiButton: [ + { + matcher: { variant: 'dashed' }, + styles: { + padding: '5px 15px', + border: `5px dashed ${outerTheme.palette.primary.main}`, + }, }, - }, - { - matcher: { variant: 'dashed', color: 'secondary' }, - styles: { - border: `5px dashed ${outerTheme.palette.secondary.main}`, + { + matcher: { variant: 'dashed', color: 'secondary' }, + styles: { + border: `5px dashed ${outerTheme.palette.secondary.main}`, + }, }, - }, - ], - }, -}); + ], + }, + }); export default function GlobalThemeVariants() { const classes = useStyles(); diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.tsx b/docs/src/pages/customization/components/GlobalThemeVariants.tsx index e24b1e0a867aae..5c91e9c20ed9b9 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.tsx +++ b/docs/src/pages/customization/components/GlobalThemeVariants.tsx @@ -21,25 +21,26 @@ const useStyles = makeStyles((theme: Theme) => ({ }, })); -const theme = (outerTheme: Theme) => createMuiTheme({ - variants: { - MuiButton: [ - { - matcher: { variant: 'dashed' }, - styles: { - padding: '5px 15px', - border: `5px dashed ${outerTheme.palette.primary.main}`, +const theme = (outerTheme: Theme) => + createMuiTheme({ + variants: { + MuiButton: [ + { + matcher: { variant: 'dashed' }, + styles: { + padding: '5px 15px', + border: `5px dashed ${outerTheme.palette.primary.main}`, + }, }, - }, - { - matcher: { variant: 'dashed', color: 'secondary' }, - styles: { - border: `5px dashed ${outerTheme.palette.secondary.main}`, + { + matcher: { variant: 'dashed', color: 'secondary' }, + styles: { + border: `5px dashed ${outerTheme.palette.secondary.main}`, + }, }, - }, - ], - }, -}); + ], + }, + }); export default function GlobalThemeVariants() { const classes = useStyles(); From 4f34120e57b4107eb74ce6c542c0bc32953e1899 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 12 Jul 2020 10:13:56 +0200 Subject: [PATCH 40/81] example updated --- .../src/pages/customization/components/GlobalThemeVariants.js | 4 ++-- .../pages/customization/components/GlobalThemeVariants.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.js b/docs/src/pages/customization/components/GlobalThemeVariants.js index ca90092dd01373..3b2d40e322f572 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.js +++ b/docs/src/pages/customization/components/GlobalThemeVariants.js @@ -14,7 +14,7 @@ const useStyles = makeStyles((theme) => ({ }, })); -const theme = (outerTheme) => +const inputTheme = (outerTheme) => createMuiTheme({ variants: { MuiButton: [ @@ -39,7 +39,7 @@ export default function GlobalThemeVariants() { const classes = useStyles(); return ( - +
-
-
+
+ ); } diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.tsx b/docs/src/pages/customization/components/GlobalThemeVariants.tsx index 060afadf9d2867..bb2bbea49f8d43 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.tsx +++ b/docs/src/pages/customization/components/GlobalThemeVariants.tsx @@ -21,38 +21,39 @@ const useStyles = makeStyles((theme: Theme) => ({ }, })); -const inputTheme = (outerTheme: Theme) => - createMuiTheme({ - variants: { - MuiButton: [ - { - matcher: { variant: 'dashed' }, - styles: { - padding: '5px 15px', - border: `5px dashed ${outerTheme.palette.primary.main}`, - }, +const defaultTheme = createMuiTheme(); + +const inputTheme = createMuiTheme({ + variants: { + MuiButton: [ + { + matcher: { variant: 'dashed' }, + styles: { + padding: '5px 15px', + border: `5px dashed ${defaultTheme.palette.primary.main}`, }, - { - matcher: { variant: 'dashed', color: 'secondary' }, - styles: { - border: `5px dashed ${outerTheme.palette.secondary.main}`, - }, + }, + { + matcher: { variant: 'dashed', color: 'secondary' }, + styles: { + border: `5px dashed ${defaultTheme.palette.secondary.main}`, }, - ], - }, - }); + }, + ], + }, +}); export default function GlobalThemeVariants() { const classes = useStyles(); return ( - -
+
+ -
- + +
); } From bb687a482b705702d521248dee0142241eb97e7e Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 18 Jul 2020 13:38:13 +0200 Subject: [PATCH 43/81] prettier --- .../material-ui-styles/src/getStylesCreator/getStylesCreator.js | 2 +- packages/material-ui/src/Button/Button.d.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 3cc0bbee803f82..c27fedfbf467ab 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -13,7 +13,7 @@ export function capitalize(string) { function isEmpty(string) { return string.length === 0; -}; +} const propsToClassKey = (matcher) => { const { variant, ...rest } = matcher; diff --git a/packages/material-ui/src/Button/Button.d.ts b/packages/material-ui/src/Button/Button.d.ts index 5078f3ee355e7b..023222cf43b7b7 100644 --- a/packages/material-ui/src/Button/Button.d.ts +++ b/packages/material-ui/src/Button/Button.d.ts @@ -1,4 +1,3 @@ -import { PropTypes } from '..'; import { OverridableStringUnion } from '@material-ui/types'; import { ExtendButtonBase, ExtendButtonBaseTypeMap } from '../ButtonBase'; import { OverrideProps, OverridableComponent, OverridableTypeMap } from '../OverridableComponent'; From 4efaf62aa7d56d3ff5a730c36a532e4ea5205475 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 18 Jul 2020 13:45:03 +0200 Subject: [PATCH 44/81] lint --- packages/material-ui/src/styles/variants.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/styles/variants.d.ts b/packages/material-ui/src/styles/variants.d.ts index 7a30660b50c09f..5f4a3b3f00c8c9 100644 --- a/packages/material-ui/src/styles/variants.d.ts +++ b/packages/material-ui/src/styles/variants.d.ts @@ -1,5 +1,5 @@ -import { ComponentsPropsList } from './props'; import { CSSProperties, CreateCSSProperties, PropsFunc } from '@material-ui/styles/withStyles'; +import { ComponentsPropsList } from './props'; export type Variants = { [Name in keyof ComponentsPropsList]?: Array<{ From 18de55891b8a0ed5759ba91749a298e03aaa8734 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 19 Jul 2020 10:29:30 +0200 Subject: [PATCH 45/81] Update packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js Co-authored-by: Olivier Tassinari --- .../src/getStylesCreator/getStylesCreator.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index c27fedfbf467ab..1a04dcff7a965a 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -86,7 +86,8 @@ export default function getStylesCreator(stylesOrCreator) { [ 'Material-UI: You are trying to override a style that does not exist.', `Fix the \`${key}\` key of \`theme.overrides.${name}\`.`, - 'If you intentionally wanted to add new key, please use the theme.variants option', + '', + 'If you intentionally wanted to add a new key, please use the theme.variants option.', ].join('\n'), ); } From 4cb0b0348aa31c766732e9f28e4a11fd9c5c7c9f Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 19 Jul 2020 10:30:45 +0200 Subject: [PATCH 46/81] Update packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js Co-authored-by: Olivier Tassinari --- .../material-ui-styles/src/getStylesCreator/getStylesCreator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 1a04dcff7a965a..8fdd1c503569fb 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -2,7 +2,7 @@ import { deepmerge } from '@material-ui/utils'; import MuiError from '@material-ui/utils/macros/MuiError.macro'; import noopTheme from './noopTheme'; -// TODO: remove this once the capiitalize is moved to the @material-ui/utils package +// TODO: remove this once the capitalize method is moved to the @material-ui/utils package export function capitalize(string) { if (typeof string !== 'string') { throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); From e780712eb9c900c3e5ec44b58495220b842209ff Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 19 Jul 2020 10:31:12 +0200 Subject: [PATCH 47/81] Update docs/src/pages/customization/components/components.md Co-authored-by: Olivier Tassinari --- docs/src/pages/customization/components/components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/customization/components/components.md b/docs/src/pages/customization/components/components.md index 9e244712cef1ad..f9627dcfb45d6d 100644 --- a/docs/src/pages/customization/components/components.md +++ b/docs/src/pages/customization/components/components.md @@ -346,7 +346,7 @@ const theme = createMuiTheme({ }); ``` -If you are using typescript, you will need to specify your new variants/colors, using module augmentation. +If you are using TypeScript, you will need to specify your new variants/colors, using module augmentation. ```tsx declare module '@material-ui/core/Button/Button' { From eb02491ae9559e5cee155ec6d5dbeadf20075d09 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 19 Jul 2020 11:13:29 +0200 Subject: [PATCH 48/81] added test --- .../src/withStyles/withStyles.test.js | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/material-ui-styles/src/withStyles/withStyles.test.js b/packages/material-ui-styles/src/withStyles/withStyles.test.js index 6f4bcfb0734b42..c950e36582818d 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.test.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.test.js @@ -235,6 +235,36 @@ describe('withStyles', () => { expect(sheetsRegistry.registry[0].rules.raw).to.deep.equal({ root: { padding: 9 } }); }); + it('should support the variants key', () => { + const styles = {}; + const StyledComponent = withStyles(styles, { name: 'MuiButton' })(() =>
); + const generateClassName = createGenerateClassName(); + const sheetsRegistry = new SheetsRegistry(); + + render( + + + + + , + ); + + expect(sheetsRegistry.registry.length).to.equal(1); + expect(sheetsRegistry.registry[0].rules.raw).to.deep.equal({ test: { padding: 9 }, testSizeLarge: { fontSize: 20 } }); + }); + describe('options: disableGeneration', () => { it('should not generate the styles', () => { const styles = { root: { display: 'flex' } }; From bb5baa1c3f3ce187461eae4197c85d1e1321c5f9 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 19 Jul 2020 11:23:18 +0200 Subject: [PATCH 49/81] prettier --- .../src/withStyles/withStyles.test.js | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/material-ui-styles/src/withStyles/withStyles.test.js b/packages/material-ui-styles/src/withStyles/withStyles.test.js index c950e36582818d..5b56c498df5a8e 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.test.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.test.js @@ -245,13 +245,16 @@ describe('withStyles', () => { @@ -262,7 +265,10 @@ describe('withStyles', () => { ); expect(sheetsRegistry.registry.length).to.equal(1); - expect(sheetsRegistry.registry[0].rules.raw).to.deep.equal({ test: { padding: 9 }, testSizeLarge: { fontSize: 20 } }); + expect(sheetsRegistry.registry[0].rules.raw).to.deep.equal({ + test: { padding: 9 }, + testSizeLarge: { fontSize: 20 }, + }); }); describe('options: disableGeneration', () => { From 3e1ea72b72e61bc178eb46b84280afc15b5962e2 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 19 Jul 2020 18:47:00 +0200 Subject: [PATCH 50/81] Update docs/src/pages/customization/components/components.md Co-authored-by: Matt --- docs/src/pages/customization/components/components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/customization/components/components.md b/docs/src/pages/customization/components/components.md index f9627dcfb45d6d..0e18ba22425e74 100644 --- a/docs/src/pages/customization/components/components.md +++ b/docs/src/pages/customization/components/components.md @@ -322,7 +322,7 @@ const theme = createMuiTheme({ ### Adding new theme variants -You can take advantage of the `variants` key of the `theme` to potentially add new variants for the Material-UI components. +You can take advantage of the `variants` key of the `theme` to add new variants to Material-UI components. ```jsx const theme = createMuiTheme({ From 90609ffc093027de650f5f57dbccc0a9ac9af719 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 19 Jul 2020 18:47:11 +0200 Subject: [PATCH 51/81] Update docs/src/pages/customization/components/components.md Co-authored-by: Matt --- docs/src/pages/customization/components/components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/customization/components/components.md b/docs/src/pages/customization/components/components.md index 0e18ba22425e74..167f5935c1979d 100644 --- a/docs/src/pages/customization/components/components.md +++ b/docs/src/pages/customization/components/components.md @@ -320,7 +320,7 @@ const theme = createMuiTheme({ {{"demo": "pages/customization/components/GlobalThemeOverride.js"}} -### Adding new theme variants +### Adding new component variants You can take advantage of the `variants` key of the `theme` to add new variants to Material-UI components. From c4df8791ec13f5a071451c6a5296cafdd790de52 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 20 Jul 2020 10:26:38 +0200 Subject: [PATCH 52/81] added warning, renamed matcher to props --- .../components/GlobalThemeVariants.js | 4 ++-- .../components/GlobalThemeVariants.tsx | 4 ++-- .../customization/components/components.md | 4 ++-- .../src/getStylesCreator/getStylesCreator.js | 12 ++++++------ .../src/makeStyles/makeStyles.js | 17 +++++++++++++++++ .../src/withStyles/withStyles.test.js | 9 +++++++-- packages/material-ui/src/styles/variants.d.ts | 2 +- 7 files changed, 37 insertions(+), 15 deletions(-) diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.js b/docs/src/pages/customization/components/GlobalThemeVariants.js index 3a6e9cb3fe9c37..7514ee4321bc57 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.js +++ b/docs/src/pages/customization/components/GlobalThemeVariants.js @@ -20,14 +20,14 @@ const inputTheme = createMuiTheme({ variants: { MuiButton: [ { - matcher: { variant: 'dashed' }, + props: { variant: 'dashed' }, styles: { padding: '5px 15px', border: `5px dashed ${defaultTheme.palette.primary.main}`, }, }, { - matcher: { variant: 'dashed', color: 'secondary' }, + props: { variant: 'dashed', color: 'secondary' }, styles: { border: `5px dashed ${defaultTheme.palette.secondary.main}`, }, diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.tsx b/docs/src/pages/customization/components/GlobalThemeVariants.tsx index bb2bbea49f8d43..15bf5d0ef4908a 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.tsx +++ b/docs/src/pages/customization/components/GlobalThemeVariants.tsx @@ -27,14 +27,14 @@ const inputTheme = createMuiTheme({ variants: { MuiButton: [ { - matcher: { variant: 'dashed' }, + props: { variant: 'dashed' }, styles: { padding: '5px 15px', border: `5px dashed ${defaultTheme.palette.primary.main}`, }, }, { - matcher: { variant: 'dashed', color: 'secondary' }, + props: { variant: 'dashed', color: 'secondary' }, styles: { border: `5px dashed ${defaultTheme.palette.secondary.main}`, }, diff --git a/docs/src/pages/customization/components/components.md b/docs/src/pages/customization/components/components.md index 167f5935c1979d..8cecfab698bade 100644 --- a/docs/src/pages/customization/components/components.md +++ b/docs/src/pages/customization/components/components.md @@ -329,14 +329,14 @@ const theme = createMuiTheme({ variants: { MuiButton: [ { - matcher: { variant: 'dashed' }, + props: { variant: 'dashed' }, styles: { padding: '5px 15px', border: `5px dashed grey${blue[500]}`, }, }, { - matcher: { variant: 'dashed', color: 'secondary' }, + props: { variant: 'dashed', color: 'secondary' }, styles: { border: `5px dashed ${red[500]}`, }, diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 8fdd1c503569fb..52c686005acd55 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -15,18 +15,18 @@ function isEmpty(string) { return string.length === 0; } -const propsToClassKey = (matcher) => { - const { variant, ...rest } = matcher; +const propsToClassKey = (props) => { + const { variant, ...rest } = props; - let classKey = matcher.variant ? matcher.variant : ''; + let classKey = variant || ''; Object.keys(rest) .sort() .forEach((key) => { if (key === 'color') { - classKey += isEmpty(classKey) ? matcher[key] : capitalize(matcher[key]); + classKey += isEmpty(classKey) ? props[key] : capitalize(props[key]); } else { - classKey += `${isEmpty(classKey) ? key : capitalize(key)}${capitalize(matcher[key])}`; + classKey += `${isEmpty(classKey) ? key : capitalize(key)}${capitalize(props[key])}`; } }); @@ -97,7 +97,7 @@ export default function getStylesCreator(stylesOrCreator) { }); variants.forEach((definition) => { - const classKey = propsToClassKey(definition.matcher); + const classKey = propsToClassKey(definition.props); stylesWithOverrides[classKey] = deepmerge( stylesWithOverrides[classKey] || {}, definition.styles, diff --git a/packages/material-ui-styles/src/makeStyles/makeStyles.js b/packages/material-ui-styles/src/makeStyles/makeStyles.js index 113b1effd80d1d..accbb9c74fa594 100644 --- a/packages/material-ui-styles/src/makeStyles/makeStyles.js +++ b/packages/material-ui-styles/src/makeStyles/makeStyles.js @@ -241,6 +241,23 @@ export default function makeStyles(stylesOrCreator, options = {}) { // eslint-disable-next-line react-hooks/rules-of-hooks React.useDebugValue(classes); } + if (process.env.NODE_ENV !== 'production') { + const whitelistedComponents = ['MuiButton']; + + if ( + name && + whitelistedComponents.indexOf(name) >= 0 && + props.variant && + !classes[props.variant] + ) { + console.warn( + [ + `Material-UI: You are using a variant value [${props.variant}] for which you didn't define styles.`, + `Please use the \`theme.variants.${name}\` to define a new entry for this variant.`, + ].join('\n'), + ); + } + } return classes; }; diff --git a/packages/material-ui-styles/src/withStyles/withStyles.test.js b/packages/material-ui-styles/src/withStyles/withStyles.test.js index 5b56c498df5a8e..f427b4fbd813de 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.test.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.test.js @@ -247,13 +247,17 @@ describe('withStyles', () => { variants: { MuiButton: [ { - matcher: { variant: 'test' }, + props: { variant: 'test' }, styles: { padding: 9 }, }, { - matcher: { variant: 'test', size: 'large' }, + props: { variant: 'test', size: 'large' }, styles: { fontSize: 20 }, }, + { + props: { size: 'largest' }, + styles: { fontSize: 22 }, + }, ], }, })} @@ -268,6 +272,7 @@ describe('withStyles', () => { expect(sheetsRegistry.registry[0].rules.raw).to.deep.equal({ test: { padding: 9 }, testSizeLarge: { fontSize: 20 }, + sizeLargest: { fontSize: 22 }, }); }); diff --git a/packages/material-ui/src/styles/variants.d.ts b/packages/material-ui/src/styles/variants.d.ts index 5f4a3b3f00c8c9..2e6873fce532c8 100644 --- a/packages/material-ui/src/styles/variants.d.ts +++ b/packages/material-ui/src/styles/variants.d.ts @@ -3,7 +3,7 @@ import { ComponentsPropsList } from './props'; export type Variants = { [Name in keyof ComponentsPropsList]?: Array<{ - matcher: Partial; + props: Partial; styles: // JSS property bag | CSSProperties // JSS property bag where values are based on props From 7d4fa1d996b5c7ea307ce95b297c8d9e86152a2b Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 21 Jul 2020 15:57:43 +0200 Subject: [PATCH 53/81] tests --- .../material-ui/src/Button/Button.test.js | 3 + .../describeCustomVariantsConformance.js | 100 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 packages/material-ui/src/test-utils/describeCustomVariantsConformance.js diff --git a/packages/material-ui/src/Button/Button.test.js b/packages/material-ui/src/Button/Button.test.js index 542a63a55fe7d8..5f02ba402414fc 100644 --- a/packages/material-ui/src/Button/Button.test.js +++ b/packages/material-ui/src/Button/Button.test.js @@ -6,6 +6,7 @@ import { act, createClientRender, fireEvent } from 'test/utils/createClientRende import createServerRender from 'test/utils/createServerRender'; import Button from './Button'; import describeConformance from '../test-utils/describeConformance'; +import describeCustomVariantsConformance from '../test-utils/describeCustomVariantsConformance'; import ButtonBase from '../ButtonBase'; describe('); const button = getByRole('button'); diff --git a/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js b/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js new file mode 100644 index 00000000000000..943a8d039c6a5d --- /dev/null +++ b/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js @@ -0,0 +1,100 @@ +import { expect } from 'chai'; +import * as React from 'react'; +import { createClientRender, screen } from 'test/utils/createClientRender'; +import { + createMuiTheme, + ThemeProvider, +} from '../styles'; + +/** + * Tests whether the custom variants defined in the theme work as expected. + * + * @param {Component} - the component with it's minimal required props + * @param {string} name + * + */ +export default function describeCustomVariantsConformance(Component, name) { + describe('Material-UI custom variants', () => { + const isJSDOM = navigator.userAgent === 'node.js'; + + const render = createClientRender(); + + const WrappedComponent = ({ theme, ...props }) => { + return Content + } + + it('should map the variant classkey to the component', () => { + if (isJSDOM) { + this.skip(); + } + + const theme = createMuiTheme({ + variants: { + [name]: [ + { + props: { variant: 'test' }, + styles: { backgroundColor: 'rgb(255, 0, 0)' }, + } + ] + }, + }); + + render(); + + const style = window.getComputedStyle(screen.getByTestId('component')); + expect(style.getPropertyValue('background-color')).to.equal('rgb(255, 0, 0)'); + }); + + it('should map the latest props combination classkey to the component', () => { + if (isJSDOM) { + this.skip(); + } + + const theme = createMuiTheme({ + variants: { + [name]: [ + { + props: { variant: 'test' }, + styles: { backgroundColor: 'rgb(255, 0, 0)' }, + }, + { + props: { variant: 'test', size: 'large' }, + styles: { backgroundColor: 'rgb(0, 255, 0)' }, + } + ] + }, + }); + + render(); + + const style = window.getComputedStyle(screen.getByTestId('component')); + expect(style.getPropertyValue('background-color')).to.equal('rgb(0, 255, 0)'); + }); + + it('should not add classKey if all props are not a match', () => { + if (isJSDOM) { + this.skip(); + } + + const theme = createMuiTheme({ + variants: { + [name]: [ + { + props: { variant: 'test' }, + styles: { backgroundColor: 'rgb(255, 0, 0)' }, + }, + { + props: { variant: 'test', size: 'large' }, + styles: { backgroundColor: 'rgb(0, 255, 0)' }, + } + ] + }, + }); + + render(); + + const style = window.getComputedStyle(screen.getByTestId('component')); + expect(style.getPropertyValue('background-color')).not.to.equal('rgb(0, 255, 0)'); + }); + }); +} From 7ae76f7e044ae7b3f753ee6fedf68b4b54bab781 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 21 Jul 2020 16:09:25 +0200 Subject: [PATCH 54/81] tests fixes --- .../describeCustomVariantsConformance.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js b/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js index 943a8d039c6a5d..d74a0e5e087db0 100644 --- a/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js +++ b/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js @@ -15,16 +15,15 @@ import { */ export default function describeCustomVariantsConformance(Component, name) { describe('Material-UI custom variants', () => { - const isJSDOM = navigator.userAgent === 'node.js'; - const render = createClientRender(); const WrappedComponent = ({ theme, ...props }) => { return Content } - it('should map the variant classkey to the component', () => { - if (isJSDOM) { + it('should map the variant classkey to the component', function test() { + if (/jsdom/.test(window.navigator.userAgent)) { + // see https://github.com/jsdom/jsdom/issues/2953 this.skip(); } @@ -45,8 +44,9 @@ export default function describeCustomVariantsConformance(Component, name) { expect(style.getPropertyValue('background-color')).to.equal('rgb(255, 0, 0)'); }); - it('should map the latest props combination classkey to the component', () => { - if (isJSDOM) { + it('should map the latest props combination classkey to the component', function test() { + if (/jsdom/.test(window.navigator.userAgent)) { + // see https://github.com/jsdom/jsdom/issues/2953 this.skip(); } @@ -71,8 +71,9 @@ export default function describeCustomVariantsConformance(Component, name) { expect(style.getPropertyValue('background-color')).to.equal('rgb(0, 255, 0)'); }); - it('should not add classKey if all props are not a match', () => { - if (isJSDOM) { + it('should not add classKey if all props are not a match', function test() { + if (/jsdom/.test(window.navigator.userAgent)) { + // see https://github.com/jsdom/jsdom/issues/2953 this.skip(); } From c0a9d556afde517a4f62f3d5ecbd21c814c7ae50 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 21 Jul 2020 16:21:14 +0200 Subject: [PATCH 55/81] prettier --- .../describeCustomVariantsConformance.js | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js b/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js index d74a0e5e087db0..96b91744aa89d7 100644 --- a/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js +++ b/packages/material-ui/src/test-utils/describeCustomVariantsConformance.js @@ -1,10 +1,7 @@ import { expect } from 'chai'; import * as React from 'react'; import { createClientRender, screen } from 'test/utils/createClientRender'; -import { - createMuiTheme, - ThemeProvider, -} from '../styles'; +import { createMuiTheme, ThemeProvider } from '../styles'; /** * Tests whether the custom variants defined in the theme work as expected. @@ -18,8 +15,14 @@ export default function describeCustomVariantsConformance(Component, name) { const render = createClientRender(); const WrappedComponent = ({ theme, ...props }) => { - return Content - } + return ( + + + Content + + + ); + }; it('should map the variant classkey to the component', function test() { if (/jsdom/.test(window.navigator.userAgent)) { @@ -33,8 +36,8 @@ export default function describeCustomVariantsConformance(Component, name) { { props: { variant: 'test' }, styles: { backgroundColor: 'rgb(255, 0, 0)' }, - } - ] + }, + ], }, }); @@ -49,7 +52,7 @@ export default function describeCustomVariantsConformance(Component, name) { // see https://github.com/jsdom/jsdom/issues/2953 this.skip(); } - + const theme = createMuiTheme({ variants: { [name]: [ @@ -60,8 +63,8 @@ export default function describeCustomVariantsConformance(Component, name) { { props: { variant: 'test', size: 'large' }, styles: { backgroundColor: 'rgb(0, 255, 0)' }, - } - ] + }, + ], }, }); @@ -76,7 +79,7 @@ export default function describeCustomVariantsConformance(Component, name) { // see https://github.com/jsdom/jsdom/issues/2953 this.skip(); } - + const theme = createMuiTheme({ variants: { [name]: [ @@ -87,8 +90,8 @@ export default function describeCustomVariantsConformance(Component, name) { { props: { variant: 'test', size: 'large' }, styles: { backgroundColor: 'rgb(0, 255, 0)' }, - } - ] + }, + ], }, }); From f88803655eaa3dbf06bbc96d300a922af94e3099 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 21 Jul 2020 16:25:44 +0200 Subject: [PATCH 56/81] prettier --- docs/src/modules/components/Ad.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/modules/components/Ad.js b/docs/src/modules/components/Ad.js index 70805c1f5d921c..0a216aea696942 100644 --- a/docs/src/modules/components/Ad.js +++ b/docs/src/modules/components/Ad.js @@ -96,7 +96,8 @@ const inHouseAds = [ link: 'https://material-ui.com/store/items/sketch-react/?utm_source=docs&utm_medium=referral&utm_campaign=in-house-sketch', img: '/static/in-house/sketch.png', - description: 'For Sketch. A large UI kit with over 600 handcrafted Material-UI symbols 💎.', + description: + 'For Sketch. A large UI kit with over 600 handcrafted Material-UI symbols 💎.', }, { name: 'figma', From b26d20d268f802dae191ea6ddf74cf68ef75987c Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 23 Jul 2020 10:54:36 +0200 Subject: [PATCH 57/81] added logic for dynamic classkeys generation --- .../components/GlobalThemeVariants.js | 29 +++++++++++++--- .../components/GlobalThemeVariants.tsx | 29 +++++++++++++--- .../src/getStylesCreator/getStylesCreator.js | 33 +------------------ .../src/propsToClassKeys/index.d.ts | 2 ++ .../src/propsToClassKeys/index.js | 1 + .../propsToClassKeys/propsToClassKeys.d.ts | 1 + .../src/propsToClassKeys/propsToClassKeys.js | 32 ++++++++++++++++++ .../src/withStyles/withStyles.js | 22 ++++++++++++- 8 files changed, 108 insertions(+), 41 deletions(-) create mode 100644 packages/material-ui-styles/src/propsToClassKeys/index.d.ts create mode 100644 packages/material-ui-styles/src/propsToClassKeys/index.js create mode 100644 packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.d.ts create mode 100644 packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.js diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.js b/docs/src/pages/customization/components/GlobalThemeVariants.js index 7514ee4321bc57..5abb2e8448c8bd 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.js +++ b/docs/src/pages/customization/components/GlobalThemeVariants.js @@ -23,13 +23,25 @@ const inputTheme = createMuiTheme({ props: { variant: 'dashed' }, styles: { padding: '5px 15px', - border: `5px dashed ${defaultTheme.palette.primary.main}`, + border: `3px dashed ${defaultTheme.palette.primary.main}`, }, }, { props: { variant: 'dashed', color: 'secondary' }, styles: { - border: `5px dashed ${defaultTheme.palette.secondary.main}`, + border: `3px dashed ${defaultTheme.palette.secondary.main}`, + }, + }, + { + props: { variant: 'dashed', size: 'large' }, + styles: { + borderWidth: 5, + }, + }, + { + props: { variant: 'dashed', color: 'primary', size: 'large' }, + styles: { + fontWeight: 600, }, }, ], @@ -42,9 +54,18 @@ export default function GlobalThemeVariants() { return (
- + + + +
diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.tsx b/docs/src/pages/customization/components/GlobalThemeVariants.tsx index 15bf5d0ef4908a..6604c4ee035521 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.tsx +++ b/docs/src/pages/customization/components/GlobalThemeVariants.tsx @@ -30,13 +30,25 @@ const inputTheme = createMuiTheme({ props: { variant: 'dashed' }, styles: { padding: '5px 15px', - border: `5px dashed ${defaultTheme.palette.primary.main}`, + border: `3px dashed ${defaultTheme.palette.primary.main}`, }, }, { props: { variant: 'dashed', color: 'secondary' }, styles: { - border: `5px dashed ${defaultTheme.palette.secondary.main}`, + border: `3px dashed ${defaultTheme.palette.secondary.main}`, + }, + }, + { + props: { variant: 'dashed', size: 'large' }, + styles: { + borderWidth: 5, + }, + }, + { + props: { variant: 'dashed', color: 'primary', size: 'large' }, + styles: { + fontWeight: 600, }, }, ], @@ -49,9 +61,18 @@ export default function GlobalThemeVariants() { return (
- + + + +
diff --git a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js index 52c686005acd55..4287b074173f4e 100644 --- a/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js +++ b/packages/material-ui-styles/src/getStylesCreator/getStylesCreator.js @@ -1,38 +1,7 @@ import { deepmerge } from '@material-ui/utils'; -import MuiError from '@material-ui/utils/macros/MuiError.macro'; +import propsToClassKey from '../propsToClassKeys'; import noopTheme from './noopTheme'; -// TODO: remove this once the capitalize method is moved to the @material-ui/utils package -export function capitalize(string) { - if (typeof string !== 'string') { - throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); - } - - return string.charAt(0).toUpperCase() + string.slice(1); -} - -function isEmpty(string) { - return string.length === 0; -} - -const propsToClassKey = (props) => { - const { variant, ...rest } = props; - - let classKey = variant || ''; - - Object.keys(rest) - .sort() - .forEach((key) => { - if (key === 'color') { - classKey += isEmpty(classKey) ? props[key] : capitalize(props[key]); - } else { - classKey += `${isEmpty(classKey) ? key : capitalize(key)}${capitalize(props[key])}`; - } - }); - - return classKey; -}; - export default function getStylesCreator(stylesOrCreator) { const themingEnabled = typeof stylesOrCreator === 'function'; diff --git a/packages/material-ui-styles/src/propsToClassKeys/index.d.ts b/packages/material-ui-styles/src/propsToClassKeys/index.d.ts new file mode 100644 index 00000000000000..1714b66f24d200 --- /dev/null +++ b/packages/material-ui-styles/src/propsToClassKeys/index.d.ts @@ -0,0 +1,2 @@ +export { default } from './propsToClassKeys'; +export * from './propsToClassKeys'; diff --git a/packages/material-ui-styles/src/propsToClassKeys/index.js b/packages/material-ui-styles/src/propsToClassKeys/index.js new file mode 100644 index 00000000000000..e476c144161c8c --- /dev/null +++ b/packages/material-ui-styles/src/propsToClassKeys/index.js @@ -0,0 +1 @@ +export { default } from './propsToClassKeys'; diff --git a/packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.d.ts b/packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.d.ts new file mode 100644 index 00000000000000..8dc45346f87c99 --- /dev/null +++ b/packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.d.ts @@ -0,0 +1 @@ +export default function (props: object): string; diff --git a/packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.js b/packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.js new file mode 100644 index 00000000000000..f7b05f7511a1da --- /dev/null +++ b/packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.js @@ -0,0 +1,32 @@ +import MuiError from '@material-ui/utils/macros/MuiError.macro'; + +// TODO: remove this once the capitalize method is moved to the @material-ui/utils package +export function capitalize(string) { + if (typeof string !== 'string') { + throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); + } + + return string.charAt(0).toUpperCase() + string.slice(1); +} + +function isEmpty(string) { + return string.length === 0; +} + +export default function propsToClassKey(props) { + const { variant, ...rest } = props; + + let classKey = variant || ''; + + Object.keys(rest) + .sort() + .forEach((key) => { + if (key === 'color') { + classKey += isEmpty(classKey) ? props[key] : capitalize(props[key]); + } else { + classKey += `${isEmpty(classKey) ? key : capitalize(key)}${capitalize(props[key])}`; + } + }); + + return classKey; +} diff --git a/packages/material-ui-styles/src/withStyles/withStyles.js b/packages/material-ui-styles/src/withStyles/withStyles.js index bfccbf25074786..fc89cedc2a3f88 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.js @@ -5,6 +5,7 @@ import { chainPropTypes, getDisplayName } from '@material-ui/utils'; import makeStyles from '../makeStyles'; import getThemeProps from '../getThemeProps'; import useTheme from '../useTheme'; +import propsToClassKey from '../propsToClassKeys'; // Link a style sheet with a component. // It does not modify the component passed to it; @@ -48,7 +49,7 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { // The wrapper receives only user supplied props, which could be a subset of // the actual props Component might receive due to merging with defaultProps. // So copying it here would give us the same result in the wrapper as well. - const classes = useStyles({ ...Component.defaultProps, ...props }); + let classes = useStyles({ ...Component.defaultProps, ...props }); let theme; let more = other; @@ -67,6 +68,25 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { if (withTheme && !more.theme) { more.theme = theme; } + + if (theme && theme.variants && theme.variants[name]) { + let variantsClasses = ''; + const themeVariants = theme.variants[name]; + + themeVariants.forEach((themeVariant) => { + let isMatch = true; + Object.keys(themeVariant.props).forEach((key) => { + if (more[key] !== themeVariant.props[key]) { + isMatch = false; + } + }); + if (isMatch) { + variantsClasses = `${variantsClasses} ${classes[propsToClassKey(themeVariant.props)]}`; + } + }); + + classes = { ...classes, root: `${classes.root} ${variantsClasses}` }; + } } return ; From 5365b71a5d9428a60c3172678dd78a60aa1c0321 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 23 Jul 2020 10:59:59 +0200 Subject: [PATCH 58/81] merge conflicts --- test/utils/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/utils/index.js b/test/utils/index.js index 6c7e15d0f697bd..919acbd8fa08bb 100644 --- a/test/utils/index.js +++ b/test/utils/index.js @@ -1,5 +1,6 @@ export * from './components'; export { default as describeConformance } from './describeConformance'; +export { default as describeCustomVariantsConformance } from './describeCustomVariantsConformance'; export * from './createClientRender'; export { default as createMount } from './createMount'; export { default as createServerRender } from './createServerRender'; From 2916cd64764d06c091bc97881ea3e8d81317f754 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 23 Jul 2020 12:44:23 +0200 Subject: [PATCH 59/81] added tests for warnings, refactored tests --- .../src/makeStyles/makeStyles.js | 2 +- .../propsToClassKeys/propsToClassKeys.d.ts | 2 +- .../material-ui/src/Button/Button.test.js | 124 +++++++++++++++++- .../describeCustomVariantsConformance.js | 104 --------------- test/utils/index.js | 1 - 5 files changed, 123 insertions(+), 110 deletions(-) delete mode 100644 test/utils/describeCustomVariantsConformance.js diff --git a/packages/material-ui-styles/src/makeStyles/makeStyles.js b/packages/material-ui-styles/src/makeStyles/makeStyles.js index accbb9c74fa594..16ec88c21ab8a5 100644 --- a/packages/material-ui-styles/src/makeStyles/makeStyles.js +++ b/packages/material-ui-styles/src/makeStyles/makeStyles.js @@ -250,7 +250,7 @@ export default function makeStyles(stylesOrCreator, options = {}) { props.variant && !classes[props.variant] ) { - console.warn( + console.error( [ `Material-UI: You are using a variant value [${props.variant}] for which you didn't define styles.`, `Please use the \`theme.variants.${name}\` to define a new entry for this variant.`, diff --git a/packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.d.ts b/packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.d.ts index 8dc45346f87c99..6fd3659c54266d 100644 --- a/packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.d.ts +++ b/packages/material-ui-styles/src/propsToClassKeys/propsToClassKeys.d.ts @@ -1 +1 @@ -export default function (props: object): string; +export default function propsToClassKeys(props: object): string; diff --git a/packages/material-ui/src/Button/Button.test.js b/packages/material-ui/src/Button/Button.test.js index 1023a71dee71c3..06d0dc90a38a7c 100644 --- a/packages/material-ui/src/Button/Button.test.js +++ b/packages/material-ui/src/Button/Button.test.js @@ -1,15 +1,17 @@ import * as React from 'react'; +import PropTypes from 'prop-types'; import { expect } from 'chai'; import { getClasses, createMount, describeConformance, - describeCustomVariantsConformance, act, createClientRender, + screen, fireEvent, createServerRender, } from 'test/utils'; +import { ThemeProvider, createMuiTheme } from '../styles'; import Button from './Button'; import ButtonBase from '../ButtonBase'; @@ -30,8 +32,6 @@ describe('); const button = getByRole('button'); @@ -370,4 +370,122 @@ describe(' +
+ ); + }; + + WrappedComponent.propTypes = { + theme: PropTypes.object, + }; + + it('should map the variant classkey to the component', function test() { + if (/jsdom/.test(window.navigator.userAgent)) { + // see https://github.com/jsdom/jsdom/issues/2953 + this.skip(); + } + + const theme = createMuiTheme({ + variants: { + MuiButton: [ + { + props: { variant: 'test' }, + styles: { backgroundColor: 'rgb(255, 0, 0)' }, + }, + ], + }, + }); + + render(); + + const style = window.getComputedStyle(screen.getByTestId('component')); + expect(style.getPropertyValue('background-color')).to.equal('rgb(255, 0, 0)'); + }); + + it('should map the latest props combination classkey to the component', function test() { + if (/jsdom/.test(window.navigator.userAgent)) { + // see https://github.com/jsdom/jsdom/issues/2953 + this.skip(); + } + + const theme = createMuiTheme({ + variants: { + MuiButton: [ + { + props: { variant: 'test' }, + styles: { backgroundColor: 'rgb(255, 0, 0)' }, + }, + { + props: { variant: 'test', size: 'large' }, + styles: { backgroundColor: 'rgb(0, 255, 0)' }, + }, + ], + }, + }); + + render(); + + const style = window.getComputedStyle(screen.getByTestId('component')); + expect(style.getPropertyValue('background-color')).to.equal('rgb(0, 255, 0)'); + }); + + it('should not add classKey if all props are not a match', function test() { + if (/jsdom/.test(window.navigator.userAgent)) { + // see https://github.com/jsdom/jsdom/issues/2953 + this.skip(); + } + + const theme = createMuiTheme({ + variants: { + MuiButton: [ + { + props: { variant: 'test' }, + styles: { backgroundColor: 'rgb(255, 0, 0)' }, + }, + { + props: { variant: 'test', size: 'large' }, + styles: { backgroundColor: 'rgb(0, 255, 0)' }, + }, + ], + }, + }); + + render(); + + const style = window.getComputedStyle(screen.getByTestId('component')); + expect(style.getPropertyValue('background-color')).not.to.equal('rgb(0, 255, 0)'); + }); + + + it('should warn if the used variant is not defined in the theme', function test() { + const theme = createMuiTheme({ + variants: { + MuiButton: [ + { + props: { variant: 'test1' }, + styles: { backgroundColor: 'rgb(255, 0, 0)' }, + }, + ], + }, + }); + + expect(() => mount()).toErrorDev([ + [ + `Material-UI: You are using a variant value [test] for which you didn't define styles.`, + `Please use the \`theme.variants.MuiButton\` to define a new entry for this variant.`, + ].join('\n'), + [ + `Material-UI: You are using a variant value [test] for which you didn't define styles.`, + `Please use the \`theme.variants.MuiButton\` to define a new entry for this variant.`, + ].join('\n'), + ]); + }); + }); }); diff --git a/test/utils/describeCustomVariantsConformance.js b/test/utils/describeCustomVariantsConformance.js deleted file mode 100644 index 96b91744aa89d7..00000000000000 --- a/test/utils/describeCustomVariantsConformance.js +++ /dev/null @@ -1,104 +0,0 @@ -import { expect } from 'chai'; -import * as React from 'react'; -import { createClientRender, screen } from 'test/utils/createClientRender'; -import { createMuiTheme, ThemeProvider } from '../styles'; - -/** - * Tests whether the custom variants defined in the theme work as expected. - * - * @param {Component} - the component with it's minimal required props - * @param {string} name - * - */ -export default function describeCustomVariantsConformance(Component, name) { - describe('Material-UI custom variants', () => { - const render = createClientRender(); - - const WrappedComponent = ({ theme, ...props }) => { - return ( - - - Content - - - ); - }; - - it('should map the variant classkey to the component', function test() { - if (/jsdom/.test(window.navigator.userAgent)) { - // see https://github.com/jsdom/jsdom/issues/2953 - this.skip(); - } - - const theme = createMuiTheme({ - variants: { - [name]: [ - { - props: { variant: 'test' }, - styles: { backgroundColor: 'rgb(255, 0, 0)' }, - }, - ], - }, - }); - - render(); - - const style = window.getComputedStyle(screen.getByTestId('component')); - expect(style.getPropertyValue('background-color')).to.equal('rgb(255, 0, 0)'); - }); - - it('should map the latest props combination classkey to the component', function test() { - if (/jsdom/.test(window.navigator.userAgent)) { - // see https://github.com/jsdom/jsdom/issues/2953 - this.skip(); - } - - const theme = createMuiTheme({ - variants: { - [name]: [ - { - props: { variant: 'test' }, - styles: { backgroundColor: 'rgb(255, 0, 0)' }, - }, - { - props: { variant: 'test', size: 'large' }, - styles: { backgroundColor: 'rgb(0, 255, 0)' }, - }, - ], - }, - }); - - render(); - - const style = window.getComputedStyle(screen.getByTestId('component')); - expect(style.getPropertyValue('background-color')).to.equal('rgb(0, 255, 0)'); - }); - - it('should not add classKey if all props are not a match', function test() { - if (/jsdom/.test(window.navigator.userAgent)) { - // see https://github.com/jsdom/jsdom/issues/2953 - this.skip(); - } - - const theme = createMuiTheme({ - variants: { - [name]: [ - { - props: { variant: 'test' }, - styles: { backgroundColor: 'rgb(255, 0, 0)' }, - }, - { - props: { variant: 'test', size: 'large' }, - styles: { backgroundColor: 'rgb(0, 255, 0)' }, - }, - ], - }, - }); - - render(); - - const style = window.getComputedStyle(screen.getByTestId('component')); - expect(style.getPropertyValue('background-color')).not.to.equal('rgb(0, 255, 0)'); - }); - }); -} diff --git a/test/utils/index.js b/test/utils/index.js index 919acbd8fa08bb..6c7e15d0f697bd 100644 --- a/test/utils/index.js +++ b/test/utils/index.js @@ -1,6 +1,5 @@ export * from './components'; export { default as describeConformance } from './describeConformance'; -export { default as describeCustomVariantsConformance } from './describeCustomVariantsConformance'; export * from './createClientRender'; export { default as createMount } from './createMount'; export { default as createServerRender } from './createServerRender'; From e1859680dc3940fe83d8f33240e89f7e187f3dad Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 23 Jul 2020 12:50:43 +0200 Subject: [PATCH 60/81] prettier --- packages/material-ui/src/Button/Button.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/material-ui/src/Button/Button.test.js b/packages/material-ui/src/Button/Button.test.js index 06d0dc90a38a7c..96022dbd15575c 100644 --- a/packages/material-ui/src/Button/Button.test.js +++ b/packages/material-ui/src/Button/Button.test.js @@ -463,7 +463,6 @@ describe(' + + - -
); diff --git a/docs/src/pages/customization/components/GlobalThemeVariants.tsx b/docs/src/pages/customization/components/GlobalThemeVariants.tsx index 6604c4ee035521..7b7870bb589c58 100644 --- a/docs/src/pages/customization/components/GlobalThemeVariants.tsx +++ b/docs/src/pages/customization/components/GlobalThemeVariants.tsx @@ -23,32 +23,34 @@ const useStyles = makeStyles((theme: Theme) => ({ const defaultTheme = createMuiTheme(); -const inputTheme = createMuiTheme({ +const theme = createMuiTheme({ variants: { MuiButton: [ { props: { variant: 'dashed' }, styles: { - padding: '5px 15px', - border: `3px dashed ${defaultTheme.palette.primary.main}`, + textTransform: 'none', + border: `2px dashed ${defaultTheme.palette.primary.main}`, + color: defaultTheme.palette.primary.main, }, }, { props: { variant: 'dashed', color: 'secondary' }, styles: { - border: `3px dashed ${defaultTheme.palette.secondary.main}`, + border: `2px dashed ${defaultTheme.palette.secondary.main}`, + color: defaultTheme.palette.secondary.main, }, }, { props: { variant: 'dashed', size: 'large' }, styles: { - borderWidth: 5, + borderWidth: 4, }, }, { - props: { variant: 'dashed', color: 'primary', size: 'large' }, + props: { variant: 'dashed', color: 'secondary', size: 'large' }, styles: { - fontWeight: 600, + fontSize: 18, }, }, ], @@ -60,20 +62,17 @@ export default function GlobalThemeVariants() { return (
- - + + - -
); diff --git a/docs/src/pages/customization/components/components.md b/docs/src/pages/customization/components/components.md index c3d8f5d8397708..906d0010aaf041 100644 --- a/docs/src/pages/customization/components/components.md +++ b/docs/src/pages/customization/components/components.md @@ -333,14 +333,14 @@ const theme = createMuiTheme({ { props: { variant: 'dashed' }, styles: { - padding: '5px 15px', - border: `5px dashed grey${blue[500]}`, + textTransform: 'none', + border: `2px dashed grey${blue[500]}`, }, }, { props: { variant: 'dashed', color: 'secondary' }, styles: { - border: `5px dashed ${red[500]}`, + border: `4px dashed ${red[500]}`, }, }, ], diff --git a/packages/material-ui-styles/src/withStyles/withStyles.js b/packages/material-ui-styles/src/withStyles/withStyles.js index a6730362b32d7b..fdf9eb832c5192 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.js @@ -85,7 +85,7 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { } }); - classes = { ...classes, root: `${classes.root} ${variantsClasses}` }; + classes = { ...classes, root: `${classes.root}${variantsClasses}` }; } } diff --git a/packages/material-ui/src/Button/Button.test.js b/packages/material-ui/src/Button/Button.test.js index b53567542e523e..3a9fb9faec948a 100644 --- a/packages/material-ui/src/Button/Button.test.js +++ b/packages/material-ui/src/Button/Button.test.js @@ -372,10 +372,11 @@ describe('
From 4e8de25000b2963f8754ed2f299b8e958b0aed6a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 24 Jul 2020 12:33:11 +0200 Subject: [PATCH 71/81] added hook for variants --- packages/material-ui-styles/src/index.d.ts | 3 ++ packages/material-ui-styles/src/index.js | 3 ++ .../src/useThemeVariants/index.d.ts | 2 ++ .../src/useThemeVariants/index.js | 1 + .../useThemeVariants/useThemeVariants.d.ts | 1 + .../src/useThemeVariants/useThemeVariants.js | 29 +++++++++++++++++++ .../src/withStyles/withStyles.js | 20 ------------- packages/material-ui/src/Button/Button.js | 15 ++++++++++ .../material-ui/src/Button/Button.test.js | 27 +++++++++++++++++ 9 files changed, 81 insertions(+), 20 deletions(-) create mode 100644 packages/material-ui-styles/src/useThemeVariants/index.d.ts create mode 100644 packages/material-ui-styles/src/useThemeVariants/index.js create mode 100644 packages/material-ui-styles/src/useThemeVariants/useThemeVariants.d.ts create mode 100644 packages/material-ui-styles/src/useThemeVariants/useThemeVariants.js diff --git a/packages/material-ui-styles/src/index.d.ts b/packages/material-ui-styles/src/index.d.ts index 04f0677bfba08a..65d11adec915fe 100644 --- a/packages/material-ui-styles/src/index.d.ts +++ b/packages/material-ui-styles/src/index.d.ts @@ -31,6 +31,9 @@ export * from './ThemeProvider'; export { default as useTheme } from './useTheme'; export * from './useTheme'; +export { default as useThemeVariants } from './useThemeVariants'; +export * from './useThemeVariants'; + export { default as withStyles } from './withStyles'; export * from './withStyles'; diff --git a/packages/material-ui-styles/src/index.js b/packages/material-ui-styles/src/index.js index 55490730c6e870..dd9aac3207d387 100644 --- a/packages/material-ui-styles/src/index.js +++ b/packages/material-ui-styles/src/index.js @@ -58,6 +58,9 @@ export * from './ThemeProvider'; export { default as useTheme } from './useTheme'; export * from './useTheme'; +export { default as useThemeVariants } from './useThemeVariants'; +export * from './useThemeVariants'; + export { default as withStyles } from './withStyles'; export * from './withStyles'; diff --git a/packages/material-ui-styles/src/useThemeVariants/index.d.ts b/packages/material-ui-styles/src/useThemeVariants/index.d.ts new file mode 100644 index 00000000000000..d01081d333c1d2 --- /dev/null +++ b/packages/material-ui-styles/src/useThemeVariants/index.d.ts @@ -0,0 +1,2 @@ +export { default } from './useThemeVariants'; +export * from './useThemeVariants'; diff --git a/packages/material-ui-styles/src/useThemeVariants/index.js b/packages/material-ui-styles/src/useThemeVariants/index.js new file mode 100644 index 00000000000000..2ee16edd774b5e --- /dev/null +++ b/packages/material-ui-styles/src/useThemeVariants/index.js @@ -0,0 +1 @@ +export { default } from './useThemeVariants'; diff --git a/packages/material-ui-styles/src/useThemeVariants/useThemeVariants.d.ts b/packages/material-ui-styles/src/useThemeVariants/useThemeVariants.d.ts new file mode 100644 index 00000000000000..4e29e41d072ce8 --- /dev/null +++ b/packages/material-ui-styles/src/useThemeVariants/useThemeVariants.d.ts @@ -0,0 +1 @@ +export default function useThemeVariants(props: object, name: string): string; \ No newline at end of file diff --git a/packages/material-ui-styles/src/useThemeVariants/useThemeVariants.js b/packages/material-ui-styles/src/useThemeVariants/useThemeVariants.js new file mode 100644 index 00000000000000..30370d78024ae2 --- /dev/null +++ b/packages/material-ui-styles/src/useThemeVariants/useThemeVariants.js @@ -0,0 +1,29 @@ +import useTheme from '../useTheme'; +import propsToClassKey from '../propsToClassKey'; + +const useThemeVariants = (props, name) => { + const { classes = {} } = props; + const theme = useTheme(); + + let variantsClasses = ''; + if (theme && theme.variants && theme.variants[name]) { + + const themeVariants = theme.variants[name]; + + themeVariants.forEach((themeVariant) => { + let isMatch = true; + Object.keys(themeVariant.props).forEach((key) => { + if (props[key] !== themeVariant.props[key]) { + isMatch = false; + } + }); + if (isMatch) { + variantsClasses = `${variantsClasses} ${classes[propsToClassKey(themeVariant.props)]}`; + } + }); + } + + return variantsClasses; +} + +export default useThemeVariants; \ No newline at end of file diff --git a/packages/material-ui-styles/src/withStyles/withStyles.js b/packages/material-ui-styles/src/withStyles/withStyles.js index fdf9eb832c5192..24fc916f8f7387 100644 --- a/packages/material-ui-styles/src/withStyles/withStyles.js +++ b/packages/material-ui-styles/src/withStyles/withStyles.js @@ -5,7 +5,6 @@ import { chainPropTypes, getDisplayName } from '@material-ui/utils'; import makeStyles from '../makeStyles'; import getThemeProps from '../getThemeProps'; import useTheme from '../useTheme'; -import propsToClassKey from '../propsToClassKey'; // Link a style sheet with a component. // It does not modify the component passed to it; @@ -68,25 +67,6 @@ const withStyles = (stylesOrCreator, options = {}) => (Component) => { if (withTheme && !more.theme) { more.theme = theme; } - - if (theme && theme.variants && theme.variants[name]) { - let variantsClasses = ''; - const themeVariants = theme.variants[name]; - - themeVariants.forEach((themeVariant) => { - let isMatch = true; - Object.keys(themeVariant.props).forEach((key) => { - if (more[key] !== themeVariant.props[key]) { - isMatch = false; - } - }); - if (isMatch) { - variantsClasses = `${variantsClasses} ${classes[propsToClassKey(themeVariant.props)]}`; - } - }); - - classes = { ...classes, root: `${classes.root}${variantsClasses}` }; - } } return ; diff --git a/packages/material-ui/src/Button/Button.js b/packages/material-ui/src/Button/Button.js index 46beddb5cd080c..b95a159665818a 100644 --- a/packages/material-ui/src/Button/Button.js +++ b/packages/material-ui/src/Button/Button.js @@ -1,6 +1,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; +import { useThemeVariants } from '@material-ui/styles'; import withStyles from '../styles/withStyles'; import { fade } from '../styles/colorManipulator'; import ButtonBase from '../ButtonBase'; @@ -278,6 +279,19 @@ const Button = React.forwardRef(function Button(props, ref) { ...other } = props; + const themeVariantsClasses = useThemeVariants({ + color, + component, + disabled, + disableElevation, + disableFocusRipple, + fullWidth, + size, + type, + variant, + ...props + }, 'MuiButton'); + const startIcon = startIconProp && ( {startIconProp} @@ -304,6 +318,7 @@ const Button = React.forwardRef(function Button(props, ref) { [classes.fullWidth]: fullWidth, [classes.colorInherit]: color === 'inherit', }, + themeVariantsClasses, className, )} component={component} diff --git a/packages/material-ui/src/Button/Button.test.js b/packages/material-ui/src/Button/Button.test.js index 3a9fb9faec948a..fc26f72b0a44ff 100644 --- a/packages/material-ui/src/Button/Button.test.js +++ b/packages/material-ui/src/Button/Button.test.js @@ -464,6 +464,33 @@ describe('