我正在尝试将Mixin从Material UI传递给样式化组件。问题是我无法找到一种将mixin值传递给样式化组件而不将其分配给css属性的方法。例如,这是不可能的:
const Example = styled.div`
${p => p.theme.mixins.toolbar};
`;
编辑:问题最终是结束符'}'旁边的分号。我相信添加分号会使样式化组件认为您是在添加普通属性,而不是mixin。
答案 0 :(得分:0)
// App/WithTheme.js
import React from 'react';
import {
MuiThemeProvider,
createMuiTheme,
withTheme as muiWithTheme,
} from '@material-ui/core/styles';
import { ThemeProvider } from 'styled-components';
import PropTypes from 'prop-types';
const muiTheme = createMuiTheme({
typography: {
useNextVariants: true,
},
});
function MaterialUiTheme(props) {
return <MuiThemeProvider theme={muiTheme}>{props.children}</MuiThemeProvider>;
}
MaterialUiTheme.propTypes = {
children: PropTypes.any,
};
const appTheme = { mode: 'light' };
function StyledComponentsTheme(props) {
return (
<ThemeProvider theme={{ app: appTheme, mui: props.theme }}>
{props.children}
</ThemeProvider>
);
}
StyledComponentsTheme.propTypes = {
children: PropTypes.any,
theme: PropTypes.object,
};
const StyledComponentsThemeWithMui = muiWithTheme()(StyledComponentsTheme);
function WithTheme(props) {
return (
<MaterialUiTheme>
<StyledComponentsThemeWithMui>
{props.children}
</StyledComponentsThemeWithMui>
</MaterialUiTheme>
);
}
WithTheme.propTypes = {
children: PropTypes.any,
};
export default WithTheme;
// App/index.js
import WithTheme from './WithTheme';
import AppStuff from './AppStuff';
export default function App() {
return (
<AppWrapper>
<WithTheme>
<AppStuff />
</WithTheme>
</AppWrapper>
);
}
// App/AppStuff.js
import styled from 'styled-components';
// import whatever else
// define AppStuff
export default const AppStuffStyled = styled(AppStuff)`
margin-top: ${props => {
console.log('styledProps', props); // manual check to see that we have theme w/ mui and app
return props.theme.mui.spacing.unit;
}};
`;
答案 1 :(得分:0)
您需要传播未调用它的mixins,如下所示:
const Example = styled.div`
${props => ({ ...props.theme.mixins.toolbar })}
`;
然而,这将返回样式对象,您可能希望将结果对象转换为css兼容的语法,如下所示:
const Example = styled.div`
${props => (Object.entries({ ...props.theme.mixins.toolbar }).reduce((styleString, [propName, propValue]) => {
if (propName.indexOf('@') !== -1) {
// iterate over media queries
return `${styleString}${propName} { ${Object.entries(propValue).reduce((ss, [pn, pv]) => {
pn = pn.replace(/([A-Z])/g, m => `-${m[0].toLowerCase()}`);
return `${ss}${pn}:${pv+(Number.isInteger(pv) ? 'px' : '')};`;
}, '')}; }`;
}
propName = propName.replace(/([A-Z])/g, matches => `-${matches[0].toLowerCase()}`); // convert camel-case properties into dash-splitted attributes
return `${styleString}${propName}:${propValue+(Number.isInteger(propValue) ? 'px' : '')};`; // append css pixel unit to integer values
}, ''))}
`;
答案 2 :(得分:0)
我阅读了您的修改,但删除分号对我不起作用。这可行:
import React from "react";
import { createMuiTheme } from "@material-ui/core/styles";
import styled, { ThemeProvider } from "styled-components";
const Content = styled.div`
toolbar: ${props => props.theme.mixins.toolbar};
`;
const theme = createMuiTheme();
const Wrapper = props => {
return (
<ThemeProvider theme={theme}>
<Content children={props.children} />
</ThemeProvider>
);
};
export default Wrapper;