如何扩展或合并样式化组件主题

时间:2018-10-29 22:33:58

标签: javascript css reactjs styled-components

我有一个基于样式的组件的组件库,它具有自己的主题设置集,在大多数情况下,这些主题设置永远都不会被覆盖。我正在将该组件库拉入另一个也使用样式组件并具有自己主题的项目中。如何从组件库和该项目中导入组件,并确保每个组件仅从其对应的存储库中获得主题值?我不想覆盖我的组件库主题,我想管理2个单独的主题,以便我的组件库可以访问默认主题,而另一个项目可以为其自己的组件定义一个单独的主题对象

示例: 单独的项目

const theme = {
  colors: {
    error: '#f23f3f',
  }
}

import { SeparateProjectThemeProvider } from 'separate-proj';

class App extends React.Component {
 render () {
  return (
   <SeparateProjectThemeProvider theme={theme}>
     <h1>Hello</h1>
   </SeparateProjectThemeProvider>
  )
 }
}

组件库

const theme = {
  colors: {
    brand: '#3bbdca',
  }
}

import { ThemeProvider } from "styled-components";

import defaultTheme from "./theme-settings";

const mergeThemes = (theme1, theme2) => {
  const mergedTheme = { ...theme1, ...theme2 };
  return mergedTheme;
};

const CustomThemeProvider = props => {
  const customTheme = {
    custom: Object.assign({}, defaultTheme)
  };

  return (
    <ThemeProvider theme={mergeThemes(customTheme, props.theme)}>
        {props.children}
    </ThemeProvider>
  );
};

export default CustomThemeProvider;

1 个答案:

答案 0 :(得分:1)

下面的代码将演示几个选项-用适当的主题提供程序(WrappedTitle)预包装每个component-lib组件,或在使用它们时进行包装(“ Hello Component World!”部分)。

// Sample component-lib/index.js
import React from 'react';
import styled from "styled-components";
import {ThemeProvider} from "styled-components";

const theme = {
  titleColor: "green"
};
export const CompLibThemeProvider = props => {
  const customTheme = Object.assign({}, theme, props.theme);
  return (
    <ThemeProvider theme={customTheme}>
        {props.children}
    </ThemeProvider>
  );
};

export const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: ${props => props.theme.titleColor};
`;
export const WrappedTitle = (props) => {
  return (<CompLibThemeProvider><Title {...props}/></CompLibThemeProvider>);
};

这是一些示例项目代码:

// App.js
import React from 'react';
import styled from 'styled-components';
import {Title, CompLibThemeProvider, WrappedTitle} from 'component-lib';
import {ThemeProvider} from "styled-components";

const theme = {
  titleColor: "red"
};

export const BigTitle = styled.h1`
  font-size: 5em;
  text-align: center;
  color: ${props => props.theme.titleColor};
`;

const ProjectThemeProvider = props => {

  return (
    <ThemeProvider theme={Object.assign({}, theme, props.theme)}>
        {props.children}
    </ThemeProvider>
  );
};
const App = () => {
  return (
    <>
    <ProjectThemeProvider>
      <>
        <BigTitle>Hello Big World!</BigTitle>
        <WrappedTitle>Hello Pre-wrapped World!</WrappedTitle>
      </>
    </ProjectThemeProvider>
    <CompLibThemeProvider><Title>Hello Component World!</Title></CompLibThemeProvider>
    </>
  );
}

export default App;