Giter VIP home page Giter VIP logo

antd-theme's Introduction

antd-theme

Provide runtime dynamic theme for ant design.

Features

  • Quick synchronous theme switching.
  • Support real-time modification of color / dimension variables.
  • Small packaging size, no need to pack multiple style files.
  • Code splitting friendly.

Install

Install with npm

$ npm install --save antd-theme

Usage

It's recommended to combine antd-theme/plugin with the css-loader and less-loader

Then add the loader and the plugin to your webpack config. For example:

webpack.config.js

const AntdThemePlugin = require('antd-theme/plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.(j|t)sx?$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              plugins: [
                ['import', {
                  libraryName: 'antd',
                  style: true,
                }],
              ],
              presets: ['react-app'],
            },
          },
        ],
      },
      {
        test: /\.less$/i,
        use: [
          {
            loader: AntdThemePlugin.loader,
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'less-loader',
            options: {
              javascriptEnabled: true,
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new AntdThemePlugin({
      // Variables declared here can be modified at runtime
      variables: ['primary-color'],
      themes: [
        {
          name: 'dark',
          filename: require.resolve('antd/lib/style/themes/dark.less'),
        },
        {
          name: 'compact',
          filename: require.resolve('antd/lib/style/themes/compact.less'),
        },
      ],
    })
  ],
};

app.jsx

import { Button, Select } from 'antd';
import { ThemeProvider, useTheme } from 'antd-theme';
import React from 'react';
import ReactDOM from 'react-dom';
import { SketchPicker } from 'react-color';

const initialTheme = {
  name: 'default',
  variables: { 'primary-color': '#00ff00' },
};

const ThemeSelect = () => {
  const [{ name, variables, themes }, setTheme] = useTheme();

  return (
    <>
      <Select
        style={{ width: 100 }}
        value={name}
        onChange={
          (theme) => setTheme({ name: theme, variables })
        }
      >
        {
          themes.map(
            ({ name }) => (
              <Select.Option key={name} value={name}>
                {name}
              </Select.Option>
            )
          )
        }
      </Select>
      <SketchPicker
        color={variables['primary-color']}
        onChange={(value) => {
          // Will update all css attributes affected by primary-color
          setTheme({ name, variables: { 'primary-color': value.hex } });
        }}
      />
    </>
  );
};

const App = () => {
  const [theme, setTheme] = React.useState(initialTheme);
  return (
    <ThemeProvider
      theme={theme}
      onChange={(value) => setTheme(value)}
    >
      <ThemeSelect />
      <Button type="primary">Button</Button>
    </ThemeProvider>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

For those who are using react-app-rewire-less and customize-cra with react-app-rewired, enable javascript like this

config-overrides.js

const { override, fixBabelImports, addLessLoader, addPostcssPlugins, adjustStyleLoaders, addWebpackPlugin } = require('customize-cra');

const AntdThemePlugin = require('antd-theme/plugin');

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: true,
  }),
  addLessLoader({
    javascriptEnabled: true,
  }),
  adjustStyleLoaders(
    (loaders) => {
      loaders.use[0] = {
        loader: AntdThemePlugin.loader
      }
    }
  ),
  addWebpackPlugin(
    new AntdThemePlugin({
      themes: [
        {
          name: 'dark',
          filename: require.resolve('antd/lib/style/themes/dark.less'),
        },
        {
          name: 'compact',
          filename: require.resolve('antd/lib/style/themes/compact.less'),
        },
      ],
    })
  ),
);

Security considerations

In order for style elements to be added to the DOM, a nonce attribute may need to be attached to the elements to adhere to a CSP requirements. To provide the value, you can specify the nonce value by defining a CSPSettings object on the page in global scope:

window.CSPSettings = {
  nonce: 'nonce'
};

antd-theme's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

antd-theme's Issues

Enabling less modularity will cause the following error

Enabling less modularity will cause the following error,Antd style has been excluded when modularizing
`Failed to compile.

./node_modules/antd/es/modal/style/index.less
Error: Invalid class or id selector syntax
at Array.map ()
at Array.map ()`

Maximum call stack size exceeded compiling antd's base.less

Using 0.3.3 (thanks!), when

        {
            loader: AntdThemePlugin.loader,
        },

is added to webpack config for less files (see below),

./node_modules/antd/dist/antd.less

Module build failed (from ./node_modules/less-loader/dist/cjs.js):
.clearfix {
    .clearfix();
^
Maximum call stack size exceeded

.

At the very bottom of
node_modules/antd/lib/style/core/base.less there is

// Utility classes
.clearfix {
  .clearfix();
}

(just like under the antd-theme node_modules, which does build/run perfectly well).

Any ideas? Is some less plugin from antd-theme affecting how less treats recursion?

Here's the relevant part of webpack config (as per README.md):

 module: {

    rules: [
      {
        test: /\.less$/,
        use: [
          {
            loader: AntdThemePlugin.loader,
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                javascriptEnabled: true,
              },
            },
          },
        ]
      }, ...
    ]
  },

SyntaxError: Cannot use import statement outside a module

When using the guide in the README.md I get the following error in a Next.js project:

/Users/mark/web/formula-stocks/node_modules/antd-theme/lib/runtime.js:2
import Node from 'less/lib/less/tree/node';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at compileFunction (<anonymous>)
    at wrapSafe (internal/modules/cjs/loader.js:1116:16)
    at Module._compile (internal/modules/cjs/loader.js:1164:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:937:14)
    at Module.require (internal/modules/cjs/loader.js:1089:19)
    at require (internal/modules/cjs/helpers.js:73:18)
    at Object.<anonymous> (/Users/mark/web/formula-stocks/node_modules/antd-theme/lib/parser.js:4:17)
    at Module._compile (internal/modules/cjs/loader.js:1200:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:937:14)
    at Module.require (internal/modules/cjs/loader.js:1089:19)
    at require (internal/modules/cjs/helpers.js:73:18)
    at Object.<anonymous> (/Users/mark/web/formula-stocks/node_modules/antd-theme/lib/index.js:20:32)

Here's my next.config.js

const withSass = require('@zeit/next-sass')
const withLess = require('@zeit/next-less')
const AntdThemePlugin = require('antd-theme/plugin');

// fix: prevents error when .less files are required by node
if (typeof require !== 'undefined') {
  require.extensions['.less'] = file => { }
}

module.exports = withLess(withSass({
  lessLoaderOptions: {
    lessOptions: {
      javascriptEnabled: true
    }
  },
  webpack: (config) => {
    console.log('config', config)

    config.plugins.push(
      new AntdThemePlugin({
        themes: [
          {
            name: 'dark',
            filename: require.resolve('antd/lib/style/themes/dark.less'),
          },
          {
            name: 'compact',
            filename: require.resolve('antd/lib/style/themes/compact.less'),
          },
        ],
      })
    )

    return config
  }
}))

This part works fine and the primary color is set correctly.

However. As soon as I add a. ThemeProvider I get the SyntaxError.

versions:
"antd-theme": "^0.3.4",
"@zeit/next-less": "1.0.1",
"less": "3.0.4",
"less-loader": "6",
"less-vars-to-js": "1.3.0",

I double checked my node modules and node_modules/less/lib/less/tree/node.js does exist.

Any ideas how to solve this?

I tried using the antd-theme loader as well, but that produced other errors and couldn't even build?

Any idea how to use this with Next.js?

using craco with antd-theme

I use craco to use antd, and I am issues using this plugin. I keep getting a could not find a declaration file for module './runtime' in 'antd-theme/lib/index.tsx(8,8)'.

here's my craco config file:

const CracoLessPlugin = require("craco-less");
const {
    getThemeVariables
} = require('antd/dist/theme');
const AntdThemePlugin = require('antd-theme/plugin');

module.exports = {
    plugins: [{
        plugin: CracoLessPlugin,
        options: {
            lessLoaderOptions: {
                lessOptions: {
                    modifyVars: {
                        "@primary-color": "#1DA57A",
                        // ...getThemeVariables({
                        //     dark: true,
                        //     compact: true
                        // })
                    },
                    javascriptEnabled: true
                }
            }
        }
    }],
    webpack: {
        plugins: [new AntdThemePlugin({
            // Variables declared here can be modified at runtime
            variables: ['primary-color'],
            themes: [{
                    name: 'dark',
                    filename: require.resolve('antd/lib/style/themes/dark.less'),
                },
                {
                    name: 'compact',
                    filename: require.resolve('antd/lib/style/themes/compact.less'),
                },
            ],
        })]
    }
};

Problem with TypeScript compiling with "noImplicitAny": true

When running my project with "noImplicitAny": true I receive this error:

TypeScript error in C:/**/node_modules/antd-theme/lib/index.tsx(8,8):
Could not find a declaration file for module './runtime'. 'C:/**/node_modules/antd-theme/lib/runtime.js' implicitly has an 'any' type.  TS7016

     6 | import {
     7 |   tree, contexts, functionRegistry
  >  8 | } from './runtime';
       |        ^
     9 | 
    10 | type ThemeVariables = Record<string, any>;
    11 | 

This is because there are missing types for runtime.js. After fixing this I receive more related errors coming from index.tsx.

Edit: forgot to mention - this happens when trying to import anything from "antd-theme".

Doesn't work with react-app-rewired

I have tried to get this solution working with next.js, react-app-rewired + customize-cra and react-app-rewired vanilla.

All 3 attempts have failed for a really simple application.

the next.js and customize-cra attempts produced errors. But the vanilla react-app-rewired runs, it even displays the theme Selector and I can console log the output of useTheme. But no styles ever gets loaded.

Here's the config-overrides.js

const AntdThemePlugin = require('antd-theme/plugin');

module.exports = {
    webpack: function (config, env) {

        config.module.rules.push(
            {
                test: /\.less$/i,
                use: [
                    {
                        loader: AntdThemePlugin.loader,
                    },
                    {
                        loader: 'css-loader',
                    },
                    {
                        loader: 'less-loader',
                        options: {
                            lessOptions: {
                                javascriptEnabled: true,
                            }
                        },
                    },
                ],
            }
        )

        config.plugins.push(new AntdThemePlugin({
            // Variables declared here can be modified at runtime
            variables: ['primary-color'],
            themes: [
                {
                    name: 'default',
                    filename:  require.resolve('antd/lib/style/themes/default.less'),
                },
                {
                    name: 'dark',
                    filename: require.resolve('antd/lib/style/themes/dark.less'),
                },
                {
                    name: 'compact',
                    filename: require.resolve('antd/lib/style/themes/compact.less'),
                },
            ],
        }))

        return config;
    }
}

I also tried loading a basic .less file, and the output for this doesn't load. either :/

Please help, I have spent a full week trying to get a dynamic antd theme switcherr working with either next.js or CRA 🙏

Failed to compile dark theme using customize-cra

I'm getting this error when using customize-cra

./node_modules/antd/es/list/style/index.less

    & when (@theme = dark) {
      background: @list-customize-card-bg;
    ^
Error evaluating function `if`: Cannot read property 'eval' of undefined
      Error in ./node_modules/antd/es/list/style/customize.less (line 9, column 6)

this is my config-overrides.js

const {
  override,
  fixBabelImports,
  addLessLoader,
  addPostcssPlugins,
  adjustStyleLoaders,
  addWebpackPlugin,
} = require('customize-cra')
const AntdThemePlugin = require('antd-theme/plugin')

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: true,
  }),
  addLessLoader({
    lessOptions: {
      javascriptEnabled: true,
    },
  }),
  adjustStyleLoaders(loaders => {
    loaders.use[0] = {
      loader: AntdThemePlugin.loader,
    }
  }),
  addWebpackPlugin(
    new AntdThemePlugin({
      themes: [
        {
          name: 'dark',
          filename: require.resolve('antd/lib/style/themes/dark.less'),
        },
      ],
    })
  )
)

if I remove the dark theme, it works just fine. With compact theme works too

No variables when using only "default" theme

If I provide in themes only the default one (or if I do not provide any theme) I get this object from useTheme():

{
  name: "default"
  themes: [
    name: "default"
    variables: {}
  ]
}

Please note that there are no variables.
If I add any other theme the problem disappears (the variables are populated).
Maybe using this lib with just one theme is not really useful, but I think this could be supported just for consistency.

Release with the less-loader compat fix.

If it is not too much trouble, could you please push to npm including " fix: compatible with less-loader@5 and less-loader@6 " as we have been hitting the infamous "Less Loader has been initialized using an options object that does not match the API schema." but would ideally like to try this too compared to antd-theme-webpack-plugin?
FYI building/running site locally from master works fine and looks good - thank you for sharing this.

Unrecognized Input

I'm integrating this with webpack, my config is:

rules: [
        {
          test: /\.less$/,
          use: [
            {
              loader: AntdThemePlugin.loader,
            },
            {
              loader: 'style-loader',
            },
            {
              loader: 'css-loader',
            },
            {
              loader: 'less-loader',
              options: {
                javascriptEnabled: true,
                modifyVars: antdVariables,
              },
            },
          ],
        },
        {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              plugins: [
                [
                  'import',
                  {
                    libraryName: 'antd',
                    style: true,
                  },
                ],
              ],
            },
          },
          'eslint-loader',
        ],
      },
      ],
    },
]

But I'm getting the following error when webpack builds:

var content = (function (module) {
          ^
Unrecognised input

Error: Module parse failed: 'import' and 'export' may only appear at the top level

When using the custimze-cra example in the README.md I get the following error:

./node_modules/antd/es/card/style/index.less 5:0
Module parse failed: 'import' and 'export' may only appear at the top level (5:0)
File was processed with these loaders:
 * ./node_modules/antd-theme/plugin/loader.js
 * ./node_modules/css-loader/dist/cjs.js
 * ./node_modules/postcss-loader/src/index.js
 * ./node_modules/resolve-url-loader/index.js
 * ./node_modules/less-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| (function (module) {
| // Imports
> import ___CSS_LOADER_API_IMPORT___ from "../../../../css-loader/dist/runtime/api.js";
| var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(function(i){return i[1]});
| // Module

overrides-config.js

const { override, fixBabelImports, addLessLoader, addPostcssPlugins, adjustStyleLoaders, addWebpackPlugin } = require('customize-cra');

const AntdThemePlugin = require('antd-theme/plugin');

module.exports = override(
    fixBabelImports('import', {
        libraryName: 'antd',
        libraryDirectory: 'es',
        style: true,
    }),
    addLessLoader({
        lessOptions: {
            javascriptEnabled: true,
        }
    }),
    adjustStyleLoaders(
        (loaders) => {
            loaders.use[0] = {
                loader: AntdThemePlugin.loader
            }
        }
    ),
    addWebpackPlugin(
        new AntdThemePlugin({
            themes: [
                {
                    name: 'dark',
                    filename: require.resolve('antd/lib/style/themes/dark.less'),
                },
                {
                    name: 'compact',
                    filename: require.resolve('antd/lib/style/themes/compact.less'),
                },
            ],
        })
    ),
);

related package versions:

"antd-theme": "^0.3.4",
"babel-plugin-import": "^1.13.3",
"css-loader": "5.0.1",
"customize-cra": "1.0.0",
"less": "3.11.1",
"less-loader": "6.1.0",
"react-app-rewire-less": "2.1.3",
"react-app-rewired": "2.1.8",
"react-scripts": "4.0.1",
"style-loader": "2.0.0",

there is a problem with running the site project

I just :

  1. clone project
  2. npm install
  3. npm start

but there is an error:

  1. Error evaluating function if: Cannot read property 'eval' of undefined
  2. Variable @heading-color-dark is undefined

What should i do?

webpack.config如何修改?

能否在写详细一些? 我在webpack.config里增加那些代码不起作用,是不是和原有的getStyleLoaders冲突了

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.