Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[muiStyled] Support default theme when none is available #22791

Merged
merged 40 commits into from
Oct 2, 2020
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c2d31cc
add emotion peer dependencies
mnajdova Sep 25, 2020
5ae933f
fixed types & tests
mnajdova Sep 25, 2020
18b0668
prettier
mnajdova Sep 25, 2020
f0ef95c
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Sep 28, 2020
c7bebb8
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Sep 28, 2020
92b2d6e
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Sep 28, 2020
76256f1
wip
mnajdova Sep 28, 2020
8661306
added ThemeProvider
mnajdova Sep 28, 2020
61d7fac
exported ThemeProvider from styled-engine-sc
mnajdova Sep 28, 2020
c9fcdc1
tests wip
mnajdova Sep 28, 2020
48305e9
tests
mnajdova Sep 28, 2020
1c04d40
prettier
mnajdova Sep 28, 2020
27d9f73
Update packages/material-ui/src/styles/muiStyled.d.ts
mnajdova Sep 29, 2020
b149da5
Update packages/material-ui/src/styles/customStyled.d.ts
mnajdova Sep 29, 2020
05217a7
renamed styled -> legacy_styled, renamed customStyled -> styled
mnajdova Sep 29, 2020
3bf96aa
fixed tests
mnajdova Sep 29, 2020
551157f
added migration step, exported styled with deprecation warning
mnajdova Sep 29, 2020
a03252c
prettier
mnajdova Sep 29, 2020
179a6e2
renamed legacy_styled back to styled
mnajdova Sep 29, 2020
9878176
renamed styled to experimentalStyled
mnajdova Sep 29, 2020
17ce5d4
fix
mnajdova Sep 29, 2020
b7ccb20
specify ThemeProvider as export from emotion-theming
mnajdova Sep 29, 2020
72398c8
refactored muiStyled to be used as simple styled utility too
mnajdova Sep 29, 2020
58a1fb9
fix lint issues
mnajdova Sep 29, 2020
aac9e83
renamed muiStyled to experimentalStyled
mnajdova Sep 30, 2020
5774c19
refactored to use ThemeContext
mnajdova Sep 30, 2020
8016f92
Update packages/material-ui-styles/README.md
mnajdova Sep 30, 2020
6bc05c1
Update packages/material-ui-styles/README.md
mnajdova Sep 30, 2020
9757a00
Update packages/material-ui-styles/package.json
mnajdova Sep 30, 2020
bb880fe
Moved nesting ThemeProvider to core
mnajdova Oct 1, 2020
73d6589
Update packages/material-ui/src/styles/experimentalStyled.d.ts
mnajdova Oct 1, 2020
6e2b480
Update packages/material-ui/src/styles/experimentalStyled.d.ts
mnajdova Oct 1, 2020
0c8be58
added test
mnajdova Oct 1, 2020
a001588
fixed docs generation
mnajdova Oct 1, 2020
e676780
Update packages/material-ui/src/styles/ThemeProvider.js
mnajdova Oct 1, 2020
0298222
Update packages/material-ui/src/styles/experimentalStyled.d.ts
mnajdova Oct 1, 2020
c96062d
addressed comments
mnajdova Oct 1, 2020
3e419ac
Update packages/material-ui/src/styles/ThemeProvider.js
mnajdova Oct 2, 2020
4fccc26
Update packages/material-ui/src/styles/ThemeProvider.js
mnajdova Oct 2, 2020
dcc97fa
docs:api
mnajdova Oct 2, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 5 additions & 8 deletions docs/src/pages/components/slider-styled/ContinuousSlider.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import * as React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import { experimentalStyled as styled } from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import Slider from '@material-ui/lab/SliderStyled';
import VolumeDown from '@material-ui/icons/VolumeDown';
import VolumeUp from '@material-ui/icons/VolumeUp';

const useStyles = makeStyles({
root: {
width: 200,
},
const Root = styled('div')({
width: 200,
});

export default function ContinuousSlider() {
const classes = useStyles();
const [value, setValue] = React.useState(30);

const handleChange = (event, newValue) => {
setValue(newValue);
};

return (
<div className={classes.root}>
<Root>
<Typography id="continuous-slider" gutterBottom>
Volume
</Typography>
Expand All @@ -44,6 +41,6 @@ export default function ContinuousSlider() {
Disabled slider
</Typography>
<Slider disabled defaultValue={30} aria-labelledby="disabled-slider" />
</div>
</Root>
);
}
13 changes: 5 additions & 8 deletions docs/src/pages/components/slider-styled/ContinuousSlider.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import * as React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import { experimentalStyled as styled } from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import Slider from '@material-ui/lab/SliderStyled';
import VolumeDown from '@material-ui/icons/VolumeDown';
import VolumeUp from '@material-ui/icons/VolumeUp';

const useStyles = makeStyles({
root: {
width: 200,
},
const Root = styled('div')({
width: 200,
});

export default function ContinuousSlider() {
const classes = useStyles();
const [value, setValue] = React.useState<number>(30);

const handleChange = (
Expand All @@ -24,7 +21,7 @@ export default function ContinuousSlider() {
};

return (
<div className={classes.root}>
<Root>
<Typography id="continuous-slider" gutterBottom>
Volume
</Typography>
Expand All @@ -47,6 +44,6 @@ export default function ContinuousSlider() {
Disabled slider
</Typography>
<Slider disabled defaultValue={30} aria-labelledby="disabled-slider" />
</div>
</Root>
);
}
4 changes: 2 additions & 2 deletions packages/material-ui-lab/src/SliderStyled/SliderStyled.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { useThemeProps, muiStyled, fade, lighten, darken } from '@material-ui/core/styles';
import { useThemeProps, experimentalStyled, fade, lighten, darken } from '@material-ui/core/styles';
import { capitalize } from '@material-ui/core/utils';
import SliderUnstyled from '../SliderUnstyled';
import ValueLabelStyled from './ValueLabelStyled';
Expand Down Expand Up @@ -48,7 +48,7 @@ const overridesResolver = (props, styles, name) => {
return styleOverrides;
};

const SliderRoot = muiStyled(
const SliderRoot = experimentalStyled(
'span',
{},
{ muiName: 'MuiSlider', overridesResolver },
Expand Down
4 changes: 2 additions & 2 deletions packages/material-ui-lab/src/SliderStyled/ValueLabelStyled.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { useThemeProps, muiStyled } from '@material-ui/core/styles';
import { useThemeProps, experimentalStyled } from '@material-ui/core/styles';
import ValueLabelUnstyled from '../SliderUnstyled/ValueLabelUnstyled';

const overridesResolver = (_, styles) => {
Expand All @@ -16,7 +16,7 @@ const overridesResolver = (_, styles) => {
return styleOverrides;
};

const ValueLabelRoot = muiStyled(
const ValueLabelRoot = experimentalStyled(
'span',
{},
{ muiName: 'PrivateValueLabel', overridesResolver },
Expand Down
2 changes: 2 additions & 0 deletions packages/material-ui-styled-engine-sc/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ export default function styled(tag, options) {

return scStyled(tag);
}

export { ThemeContext } from 'styled-components';
1 change: 1 addition & 0 deletions packages/material-ui-styled-engine/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from '@emotion/styled';
export { default } from '@emotion/styled';
export { ThemeContext } from '@emotion/core';
1 change: 1 addition & 0 deletions packages/material-ui-styled-engine/src/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default } from '@emotion/styled';
export { ThemeContext } from '@emotion/core';
4 changes: 2 additions & 2 deletions packages/material-ui-styles/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ Install the package in your project directory with:

```sh
// with npm
npm install @material-ui/styles
npm install @material-ui/styles @emotion/core @emotion/styled

// with yarn
yarn add @material-ui/styles
yarn add @material-ui/styles @emotion/core @emotion/styled
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the styles package really need these new dependencies? I was under the assumption that we would try not to interfer with it, progressively making it legacy, and dropping it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only reason there were added is because the ThemeProvider is in this package. Once we move it out of the package we can drop these dependencies

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only document the import of ThemeProvider from the core. Would it work if we moved the theme provider nesting to the core?

My concern is about the migration experience for v4 developers that are using JSS. We could imagine having developers migrate their v4 imports from @material-ui/core/styles to @material-ui/styles and have still everything working. We could no longer have @material-ui/styles as a dependency in @material-ui/core. Would that work? Do you have an alternative story in mind? A migration from @material-ui/core/styles to react-jss won't be as smooth.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see what is the concern. Let me try then to migrate the nesting to the core 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 👍

```

## Documentation
Expand Down
4 changes: 4 additions & 0 deletions packages/material-ui-styles/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@
"typescript": "tslint -p tsconfig.json \"{src,test}/**/*.{spec,d}.{ts,tsx}\" && tsc -p tsconfig.json"
},
"peerDependencies": {
"@emotion/core": "^10.0.27",
"@emotion/styled": "^10.0.27",
"@types/react": "^16.8.6",
"emotion-theming": "^10.0.27",
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
"react": "^16.8.0",
"react-dom": "^16.8.0"
},
Expand All @@ -49,6 +52,7 @@
"dependencies": {
"@babel/runtime": "^7.4.4",
"@emotion/hash": "^0.8.0",
"@material-ui/styled-engine": "^5.0.0-alpha.11",
"@material-ui/types": "^5.1.0",
"@material-ui/utils": "^5.0.0-alpha.8",
"clsx": "^1.0.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { exactProp } from '@material-ui/utils';
import { ThemeContext as StyledEngineThemeContext } from '@material-ui/styled-engine';
import ThemeContext from '../useTheme/ThemeContext';
import useTheme from '../useTheme';
import nested from './nested';
Expand Down Expand Up @@ -61,7 +62,13 @@ function ThemeProvider(props) {
return output;
}, [localTheme, outerTheme]);

return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>;
return (
<ThemeContext.Provider value={theme}>
<StyledEngineThemeContext.Provider value={typeof theme === 'object' ? theme : {}}>
{children}
</StyledEngineThemeContext.Provider>
</ThemeContext.Provider>
);
}

ThemeProvider.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export type PropsOf<
export type Omit<T, U> = T extends any ? Pick<T, Exclude<keyof T, U>> : never;
export type Overwrapped<T, U> = Pick<T, Extract<keyof T, keyof U>>;

type JSXInEl = JSX.IntrinsicElements;
export type JSXInEl = JSX.IntrinsicElements;
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
type ReactClassPropKeys = keyof React.ClassAttributes<any>;

export type WithTheme<P, T> = P extends { theme: infer Theme }
Expand Down Expand Up @@ -183,7 +183,7 @@ interface MuiStyledOptions<Theme extends object = any> {
overridesResolver?: (props: any, styles: string | object, name: string) => string | object;
}

export interface CreateStyled<Theme extends object = any> {
export interface CreateMUIStyled<Theme extends object = any> {
<Tag extends React.ComponentType<any>, ExtraProps = {}>(
tag: Tag,
options?: StyledOptions,
Expand All @@ -198,11 +198,13 @@ export interface CreateStyled<Theme extends object = any> {
}

/**
* Cutom styled functionality that support mui specific config.
* Custom styled utility that has a default MUI theme.
*
* @param options Takes an incomplete theme object and adds the missing parts.
* @returns A complete, ready to use theme object.
* @param tag HTML tag or component that should serve as base.
* @param options Styled options for the created component.
* @muiOptions Material-UI specific style options, consiting of overrides resolver.
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
* @returns React component that has styles attached to it.
*/
declare const muiStyled: CreateStyled;
declare const experimentalStyled: CreateMUIStyled;

export default muiStyled;
export default experimentalStyled;
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ import styled from '@material-ui/styled-engine';
import { propsToClassKey } from '@material-ui/styles';
import defaultTheme from './defaultTheme';

function isEmpty(obj) {
let result = true;

Object.keys(obj).forEach((key) => {
if (obj.hasOwnProperty(key)) {
eps1lon marked this conversation as resolved.
Show resolved Hide resolved
result = false;
}
});

return result;
}

const getStyleOverrides = (name, theme) => {
let styleOverrides = {};

Expand Down Expand Up @@ -41,7 +53,7 @@ const variantsResolver = (props, styles, theme, name) => {
themeVariants.forEach((themeVariant) => {
let isMatch = true;
Object.keys(themeVariant.props).forEach((key) => {
if (styleProps[key] !== themeVariant.props[key]) {
if (styleProps[key] !== themeVariant.props[key] && props[key] !== themeVariant.props[key]) {
isMatch = false;
}
});
Expand All @@ -56,25 +68,34 @@ const variantsResolver = (props, styles, theme, name) => {

const shouldForwardProp = (prop) => prop !== 'styleProps' && prop !== 'theme';

const muiStyled = (tag, options, muiOptions) => {
const experimentalStyled = (tag, options, muiOptions = {}) => {
const name = muiOptions.muiName;
const defaultStyledResolver = styled(tag, { shouldForwardProp, label: name, ...options });
const muiStyledResolver = (...styles) => {
if (muiOptions.overridesResolver) {
styles.push((props) => {
const theme = props.theme || defaultTheme;
const stylesWithDefaultTheme = styles.map((stylesArg) => {
return typeof stylesArg === 'function'
? ({ theme: themeInput, ...rest }) =>
stylesArg({ theme: isEmpty(themeInput) ? defaultTheme : themeInput, ...rest })
eps1lon marked this conversation as resolved.
Show resolved Hide resolved
: stylesArg;
});

if (name && muiOptions.overridesResolver) {
stylesWithDefaultTheme.push((props) => {
const theme = isEmpty(props.theme) ? defaultTheme : props.theme;
return muiOptions.overridesResolver(props, getStyleOverrides(name, theme), name);
});
}

styles.push((props) => {
const theme = props.theme || defaultTheme;
return variantsResolver(props, getVariantStyles(name, theme), theme, name);
});
if (name) {
stylesWithDefaultTheme.push((props) => {
const theme = isEmpty(props.theme) ? defaultTheme : props.theme;
return variantsResolver(props, getVariantStyles(name, theme), theme, name);
});
}

return defaultStyledResolver(...styles);
return defaultStyledResolver(...stylesWithDefaultTheme);
};
return muiStyledResolver;
};

export default muiStyled;
export default experimentalStyled;