Create Dynamic theme with antd and reactjs - reactjs

i am creating a web application using reactjs and antd. Now i want to add a feature in which user will select color and all the primary color or web application will be changed. I did searched on google but most of the people says that its not possible using antd . Just wondering if someone has tried before or is it doable ?

Antd supports setting a custom theme. You should use that to generate a theme based on what color the user chooses.
Example theme.js:
module.exports = () => {
return {
'primary-color': '#1DA57A',
'link-color': '#1DA57A',
'border-radius-base': '2px',
};
};

Related

Darkmode not working on tailwind headless UI

Darkmode works everywhere in my react app, except on a headless ui combobox. I put a styled h1 in the same component and applied dark:bg-red-200(and any other style) no problem. The combobox accept all other tailwind utilities including attibutes like hover: but not the dark: property.
For others (such as me) stumbling upon this:
E.g. the Dialog-component (and I assume others too) render right in the body tag (source)
If you are using "the class strategy" to handle dark mode (i.e. adding a "dark" class to the wrapper) this will be a problem, because the class is not anymore parent to the Dialog
Solution I ended up using:
I ended up using useEffect to add the dark class to the body:
useEffect(() => {
if(darkMode){
document.body.classList.add('dark')
}else{
document.body.classList.remove('dark')
}
}, [darkMode])

Docusaurus 2 How to add custom react component in navbar

From the docusaurus docs, the navbar items can only have certain types like link, dropdown and search.
How do I add custom buttons like if I want to add login button ?
This would really depend on the type of functionality you're wanting to see out of the item you add to the navbar, but the development patterns should be similar across various implementations.
If you're trying to trigger something like a login modal when the user clicks your custom button, you could specify the following in docusaurus.config.js:
module.exports = {
themeConfig: {
navbar: {
items: [
{
href: '#login',
label: 'Login'
}
]
}
},
scripts: [
'https://yourdomain.com/customscript.js'
]
};
Then in a script, customscript.js, you could include the following:
document.querySelector('[href="#login"]')
.addEventListener('click', () => {
console.log('Login button clicked.');
});
Docusaurus requires that either href or to is given on each navbar item, so that's why I chose the weird selector, but if you wished, you could also specify className on the item, and then use that as a selector too. If you want the item to be something other than a link, you could set the outerHTML in your custom script or use replaceWith().
Keep in-mind that depending on the way your site's routing is configured, you may need to re-apply the logic in your custom script if the link node is re-written to the DOM by React.
As far as I know, there isn't really a perfect way to accomplish this at the moment, but v2 is also still in development, so the plugin exposures are getting better with each release.
The temporary workaround works well
https://github.com/facebook/docusaurus/issues/7227

Dynamically changing Less variables in React Gatsby app with Ant Design at runtime

We are building a White Label platform using React, GatsbyJs and Ant Design. We are stuck with Gatsby and Ant Design because we are migrating from an existing system and changing any of those would bring huge impact. Also, we must have a single deploy. Having a build for each White Label is not an option.
So, we need to be able to change style (mainly color) at runtime.
The problem is: Ant Design uses less variables to define it's themes and we're not able to change them at runtime, not even with less's modifyVars.
The thing is we MUST change less variables, and not global CSS or use other means
Ant Design derivates the main variables many times to get adjacent properties. So, for instance, if we define #primary-color as red, when we add a Button to the screen, Ant Design also defines it's border color, hover color, and many other details with different shades of red.
This means that, if we were to use other styling tool, we would need to generate those color derivations and replace every little property for every component. This would be chaos.
Scenario
We are using gatsby-plugin-antd and gatsby-plugin-less to load less and change vars at build time. Our gatsby-config.js looks like this:
module.exports = {
siteMetadata: {
siteUrl: 'https://www.yourdomain.tld',
title: 'yourtitle'
},
plugins: [
'gatsby-plugin-root-import',
'gatsby-plugin-typescript',
{
resolve: 'gatsby-plugin-antd',
options: {
style: true
}
},
{
resolve: 'gatsby-plugin-less',
options: {
lessOptions: {
javascriptEnabled: true,
modifyVars: {
'primary-color': '#FFFFFF',
'link-color': '#000000',
'success-color': '#FFFFFF',
'warning-color': '#000000'
}
}
}
}
]
};
We import styling in our gatsby-browser.js file:
import './src/styles/index';
Our styles/index has:
import 'tachyons';
import './global.css';
import './antd.less';
antd.less:
#import '~antd/dist/antd.less';
And global.css has some general CSS for the project.
It's working fine with the defined variables at build time.
What we attempted so far...
We have tried out this plugin:
https://github.com/mzohaibqc/antd-theme-webpack-plugin
Which supposedly does exactly what we need. But there's no example using Gatsby.
We then tried to add the plugin using the gatsby-node.js as mentioned here:
https://www.gatsbyjs.com/docs/how-to/custom-configuration/add-custom-webpack-config/
First, we tried using index.html as the indexFileName for the pluggin. It just doesn't work.
Then, following the plugin docs, we tried using indexFileName as false and importing the following scripts using Helmet at our pages/index.tsx:
<script> window.less = { async: false, env: 'production' };
</script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js"></script> ```
Also didn't work. If we define indexFileName as false, we get memory over the heap.
If we keep indexFileName as 'index.html' and just add the scripts, we are able to call window.less.modifyVars and it returns successfully (we are logging the Promise's then and error) but it doesn't affect antd's variables.
We then tried doing something similar, but instead of loading less externally, we installed it as a node_module and imported it to the file and used it directly in a similar fashion. Got the same result: modifyVars runs and returns successfully but doesn't affect antd.
Then, we tried something a bit different: we removed gatsby plugins and tried importing less from antd directly, as suggested here:
https://ant.design/docs/react/customize-theme
So we imported it like this:
#import '~antd/lib/style/themes/default.less';
#import '~antd/dist/antd.less';
#import 'your-theme-file.less';
Also, no good. It's different from the previous scenario, because style gets updated after you save your code. No need to stop Gatsby, as the first solutions. But, modifyVars still has no affect on antd components.
Then, to isolate the issue, we tried to style a basic HTML component - a button - to check if the issue was with gatsby or antd. And... still no success. less.modifyVars didn't work to change a basic button style on runtime.
So, we think it's probably something between Gatsby and Less. We checked gatsby-plugin-antd and gatsby-plugin-less to see if we could find something, but found nothing useful.
We assume that the "less instance" or "less context" used by gatsby's less-loader during build time is not the same we are calling modifyVars on. So it doesn't affect the original vars.
Totally stuck. Please, help!
EDIT - SOLUTION
Ant Design team has just released - TODAY - a new alpha version that includes dynamic theming, using CSS Variables.
https://ant.design/docs/react/customize-theme-variable
It works fine, so far. Closing the issue.
EDIT 2
There's a more detailed solution on the accepted answer.
Ant Design team has just released - TODAY - a new alpha version that includes dynamic theming, using CSS Variables.
https://ant.design/docs/react/customize-theme-variable
It works fine, so far.
EDIT - Detailed solution
I removed gatsby-plugin-antd and gatsby-plugin-less from the project. Also removed the import of antd less file.
Instead, in my styles/index.tsx (which is imported in gatsby-browser.js), I'm importing the variables.min.css file:
import 'antd/dist/antd.variable.min.css';
Then, whenever I want to change Ant Design variables, I just use:
import { ConfigProvider } from 'antd';
...
ConfigProvider.config({
theme: {
primaryColor: '#[DESIRED_COLOR_HEX]'
}
});
Provider
Since this has to be done every time the site is loaded, I'm creating a ThemeProvider that wraps every page and defines the theme. It fetches theme data from the backend and sets Ant Design theme variables.
Example code:
import { Spin } from 'antd';
import React, { useEffect, useState } from 'react';
import { ConfigProvider } from 'antd';
import { Theme } from './theme.interface';
interface Props {
children: React.ReactNode;
}
export const ThemeProvider = ({ children }: Props): JSX.Element => {
const [themeVars, setThemeVars] = useState<Theme>(null);
useEffect(() => {
async function fetchMyAPI() {
const result = await getThemeFromBackend(); // Make API call with Axios
if (result) setThemeVars(result);
}
fetchMyAPI();
}, []);
useEffect(() => {
if (themeVars) {
ConfigProvider.config({
theme: {
primaryColor: `#${themeVars.primaryColor}`
}
});
}
}, [themeVars]);
return <div>{!themeVars ? <Spin size="large" /> : <>{children}</>}</div>;
};
And it can be used like this:
...
<ThemeProvider>
<h1>My page header</h1>
<p>Page content...</p>
</ThemeProvider>
...
Note: You can save theme data on local storage for performance improvement, so you don't have to call your backend everytime your site reloads. Maybe you'll just have to refresh it from time to time.

Support multiple themes under single build in ExtJs

I have to change the theme based on some event. What i understood from sencha docs and kitchen sink is we have to make entries of all the themes under "builds" block of app.json
"builds": {
"classic": {
"toolkit": "classic",
"theme": "theme-classic"
},
"triton": {
"toolkit": "classic",
"theme": "theme-triton"
}
},
Post build, we can reload application as below to get specific theme.
location.search = "/?profile=classic";
location.search = "/?profile=triton";
But its not working as expected. Any hints please.
You are only halfway there. Sencha Cmd will generate different manifests for your themes. Now you now have to chose the corresponding manifest upon application load. Take a look at Dynamic Manifest section from Microloader's docs.
There are times when you may want to select a build profile
client-side. To simplify this, the Microloader defines a hook method
called “Ext.beforeLoad”. If you define this method like the following,
you can control the name or content of “Ext.manifest” prior to the
Microloader processing it while leveraging its platform detection.
For your case it would look something like this:
<script type="text/javascript">
var Ext = Ext || {};
Ext.beforeLoad = function (tags) {
var theme = location.href.match(/profile=([\w-]+)/);
theme = (theme && theme[1]) || 'classic';
Ext.manifest = theme;
};
</script>

React reposinveness + bootstrap

React responsiveness
I just wanted to know how the responsiveness in to the react is possible ?
There are different ways to achieve responsive like
css-grid bootstrap-grid react-bootstrap
could some let me know what is the preferred way to do the responsive into react?
Regards,
Just use plain JS, that's the beauty of React. I personally do this:
class Responsive extends Component {
state = { isMobile: false };
componentDidMount() {
// use css media quries
this.isMobile = window.matchMedia("(max-width: 767px)");
// test on first run
this.handleIsMobile({ matches: this.isMobile.matches });
// listen to changes after first run
this.isMobile.addListener(this.handleIsMobile);
}
componentWillUnmount() {
// stop listening when unmounted
this.isMobile.removeListener(this.handleIsMobile);
}
handleIsMobile = ({ matches }) => this.setState({ isMobile: matches });
render() {
if (this.state.isMobile) return <div>MOBILE</div>;
return <div>DESKTOP</div>;
}
}
First refer this, Bootstrap webpack
This is one way of using bootstrap in reactjs projects.
The advantage of this is that u get access to latest bootstrap css.
The disadvantage of using this is its complicated to use jquery plugins in reactjs. Hovewr if you are only interested in css, then its perfect.
Using this u can directly use bootstrap classes from documentation and get more control.
Just use className instead of class
If u want simple setup , then u can use reactstrap link
Other frameworks include react-bootstrap link

Resources