передача mixins в styled-компонент - PullRequest
0 голосов
/ 29 ноября 2018

Я пытаюсь передать миксин из Material UI компоненту styled.Проблема в том, что я не могу найти способ передать значение mixin в styleled-компонент, не назначая его свойству css.Например, это невозможно:

const Example = styled.div`
  ${p => p.theme.mixins.toolbar};
`;

Редактировать: проблема оказалась в виде точки с запятой рядом с закрывающим символом '}'.Я считаю, что добавление точки с запятой заставляет стильный компонент думать, что вы добавляете обычное свойство, а не миксин.

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Вам нужно распространять миксины, не вызывая его, например так:

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
    }, ''))}
`;
0 голосов
/ 29 ноября 2018
// 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;
  }};
`;
...