简体   繁体   English

如何使用.scss文件导出的变量来创建Material-UI主题?

[英]How to use variables exported from .scss file to create Material-UI theme?

I'm trying to use some variables exported from global .scss file to create Material-UI theme.我正在尝试使用从全局.scss文件导出的一些变量来创建 Material-UI 主题。 Problems occurs because those variables are undefined on server (I'm using next.js so pages are pre-rendered).出现问题是因为这些变量在服务器上undefined (我使用的是next.js ,所以页面是预呈现的)。 How to make this work?如何使这项工作?

Error that I get (beacuse all colors are undefined ):我得到的错误(因为所有 colors 都是undefined的):

Error: Material-UI: The color provided to augmentColor(color) is invalid.
The color object needs to have a `main` property or a `500` property.

Here are the important parts of my application.这是我的应用程序的重要部分。

_app.jsx _app.jsx

// General imports
import React from 'react';

// Components import
import App from 'next/app';
import { createMuiTheme, ThemeProvider, CssBaseline, StylesProvider, jssPreset } from '@material-ui/core';
import { create } from 'jss';

// Global styles and colors import
import '../styles/global.scss';
import colors from '../styles/colors.scss';

if (typeof document !== 'undefined') {
  const styleNode = document.createComment('jss-insertion-point');
  document.head.insertBefore(styleNode, document.head.firstChild);
}

/**
 * Material-UI theme.
 *
 * @type {Object}
 */
const theme = createMuiTheme({
  palette: {
    primary: {
      main: colors.primary,
      contrastText: colors.primaryText
    },
    secondary: {
      main: colors.secondary,
      contrastText: colors.secondaryText
    }
  }
});

class CustomApp extends App {
  /**
   * Handles the componentDidMount lifecycle event.
   *
   * @memberof MyApp
   */
  componentDidMount() {
    // Remove the server-side injected CSS.
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) {
      jssStyles.parentElement.removeChild(jssStyles);
    }
  }

  /**
   * Renders the component.
   *
   * @returns component's elements
   * @memberof CustomApp
   */
  render() {
    const {
      Component,
      pageProps
    } = this.props;

    return (
     <>
        <StylesProvider
          jss={
            create({
              ...jssPreset(),
              // Define a custom insertion point that JSS will look for when injecting the styles into the DOM.
              insertionPoint: 'jss-insertion-point'
            })
          }
        >
          <ThemeProvider theme={theme}>
            <CssBaseline />
            <Component {...pageProps} />
          </ThemeProvider>
        </StylesProvider>
      </>
    );
  }
}

export default CustomApp;

_document.jsx _document.jsx

// General imports
import React from 'react';

// Components import
import Document, { Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '@material-ui/core';

/**
 *
 *
 * @class CustomDocument
 * @extends {Document}
 */
class CustomDocument extends Document {
  render() {
    return (
      <html lang="en">
        <Head>
          <meta charSet="utf-8" />
          <link rel="icon" href="/favicon.ico" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

CustomDocument.getInitialProps = async (ctx) => {
  // Render app and page and get the context of the page with collected side effects.
  const sheets = new ServerStyleSheets();
  const originalRenderPage = ctx.renderPage;

  ctx.renderPage = () => originalRenderPage({
    enhanceApp: (App) => (props) => sheets.collect(<App isServer {...props} />)
  });

  const initialProps = await Document.getInitialProps(ctx);

  return {
    ...initialProps,
    // Styles fragment is rendered after the app and page rendering finish.
    styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
    isServer: false
  };
};

export default CustomDocument;

colors.scss colors.scss

$color-primary: #2aa876;
$color-primary-text: #ffffff;
$color-secondary: #ffd265;
$color-secondary-text: #7e621d;

:export {
  primary: $color-primary;
  primaryText: $color-primary-text;
  secondary: $color-secondary;
  secondaryText: $color-secondary-text;
}

Material UI uses a javascript based style solution (JSS) instead of a CSS pre-processor like SCSS ( see style solution ). Material UI 使用基于 javascript 的样式解决方案 (JSS) 而不是像 SCSS 这样的 CSS 预处理器(参见样式解决方案)。

This means it's not possible to customize the Material UI theme via SCSS variables.这意味着无法通过 SCSS 变量自定义 Material UI 主题。 Nor is it possible to access the theme in your CSS/SCSS styles.也无法访问您的 CSS/SCSS styles 中的主题。

If you want to use SCSS for styling/theming, you might consider Material Web Components instead .如果您想将 SCSS 用于样式/主题,您可以考虑使用Material Web Components 代替

In colors.scss modify as below:colors.scss中修改如下:

$theme-colors: (
    'primary': #2aa876,
    'primaryText': #ffffff,
    'secondary': #ffd265,
    'secondaryText': #7e621d,
);


@each $color, $value in $theme-colors {
  :export{
    $color: $value;
  }
}

import it as you're doing.在你做的时候导入它。

import colors from '../styles/colors.scss'; 
# colors.primary and other variable should work now.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM