Search code examples
reactjsantdstyled-components

How to use Ant design v5 theme with style component


Antd 5.0 has been introduced their new theme system. But I wonder how to access to those design tokens of theme when I declare a component by style-component. normally I declare my component like this.

const MyComponent = styled.button`
  color:${props=> props.theme.color.primary};
`;

theme here is getting from ThemeProvider of styled component that is defined in App.jsx

<ThemeProvider theme={baseTheme}>
<App/>
</ThemeProvider>

So, theme only can access to design tokens that were defined in theme file. How can I access other tokens of Antd theme?

One way I'm thinking is creating a theme that overrides every single design token of Antd. But I think that's a bad idea


Solution

  • From the documentation consume-design-token, you can get and consume the token by using the theme.useToken() hook.

    Create a ThemeProvider get the antd theme token and combine it with base theme, then pass the combined theme to the ThemeProvider of styled-components.

    Then you can get the combined theme via passed props of styled-components.

    theme-provider.tsx:

    import { ThemeProvider } from "styled-components";
    import { theme } from "antd";
    import React from "react";
    
    export default ({ children }: React.PropsWithChildren) => {
      const { token } = theme.useToken();
      return (
        <ThemeProvider theme={{ antd: token, base: { color: "mediumseagreen" } }}>
          {children}
        </ThemeProvider>
      );
    };
    

    App.tsx:

    import styled from "styled-components";
    import { ConfigProvider } from "antd";
    import ThemeProvider from "./theme-provider";
    
    const Button = styled.button`
      color: ${(props) => {
        console.log("props.theme: ", props.theme);
        return props.theme.antd.colorPrimary;
      }};
    `;
    
    export default function App() {
      return (
        <ConfigProvider
          theme={{
            token: {
              colorPrimary: "red"
            }
          }}
        >
          <ThemeProvider>
            <Button>Hello World</Button>
          </ThemeProvider>
        </ConfigProvider>
      );
    }
    

    The log:

    props.theme:  {antd: Object, base: Object}
    

    codesandbox