Observing how they do it on the website www.primefaces.org/primereact/showcase/, open Developer view: Elements, and one can notice that choosing a different theme changes css file link in HTML header:
<link id="theme-link" rel="stylesheet" href="./themes/bootstrap4-light-blue/theme.css">
becomes
<link id="theme-link" rel="stylesheet" href="./themes/bootstrap4-light-purple/theme.css">
It is fairly easy to switch link element HREF from one to another.
This page talks about primereact theme switching: Switch Your React App Between Material, Bootstrap and Custom Themes at Runtime
But the method it describes is too convoluted, involves ejecting and custom webpack, to bundle all theme CSS files and import them programmatically, like that:
const changeTheme = (theme) => {
import(`./${theme}.scss`).then((module) => {
if (selectedThemeModule) {
selectedThemeModule.unuse();
}
module.use();
setSelectedThemeModule(module);
});
}
Instead, grab the example repo where they do method of link HREF swap: github.com/mertsincan/primereact-dynamic-theming/
example-1 has code for the convoluted method from the above page, you can skip it and go to example-2, which is much simpler.
In a nutshell, add to 'public/index.html', in <header> section:
<link id="app-theme" rel="stylesheet" type="text/css" href="saga-blue.css">
And use this function:
const changeTheme = (theme) => {
let themeLink = document.getElementById('app-theme');
if (themeLink) {
themeLink.href = theme + '.css';
}
}
Then just call changeTheme(XXX) when theme XXX is clicked.
Next put .css files into the right place - just copy all node_modules/primereact/themes/*/theme.css files into public folder (giving them corresponding theme names). Some theme.css reference fonts - search for "url" in each file, and if present, copy corresponding fonts/ directory too.
I should mention that benefits of example-1 is using minified and bundled CSS files, so themes will be switching faster. If that's important, then follow the above linked tutorial and example-1. Also note that example-2 has very similar setup to example-1 (eject and custom webpack config), but only to copy css files to the right output folder, which can be skipped in favor of copying files by hand once.
Answer from iva2k on Stack OverflowObserving how they do it on the website www.primefaces.org/primereact/showcase/, open Developer view: Elements, and one can notice that choosing a different theme changes css file link in HTML header:
<link id="theme-link" rel="stylesheet" href="./themes/bootstrap4-light-blue/theme.css">
becomes
<link id="theme-link" rel="stylesheet" href="./themes/bootstrap4-light-purple/theme.css">
It is fairly easy to switch link element HREF from one to another.
This page talks about primereact theme switching: Switch Your React App Between Material, Bootstrap and Custom Themes at Runtime
But the method it describes is too convoluted, involves ejecting and custom webpack, to bundle all theme CSS files and import them programmatically, like that:
const changeTheme = (theme) => {
import(`./${theme}.scss`).then((module) => {
if (selectedThemeModule) {
selectedThemeModule.unuse();
}
module.use();
setSelectedThemeModule(module);
});
}
Instead, grab the example repo where they do method of link HREF swap: github.com/mertsincan/primereact-dynamic-theming/
example-1 has code for the convoluted method from the above page, you can skip it and go to example-2, which is much simpler.
In a nutshell, add to 'public/index.html', in <header> section:
<link id="app-theme" rel="stylesheet" type="text/css" href="saga-blue.css">
And use this function:
const changeTheme = (theme) => {
let themeLink = document.getElementById('app-theme');
if (themeLink) {
themeLink.href = theme + '.css';
}
}
Then just call changeTheme(XXX) when theme XXX is clicked.
Next put .css files into the right place - just copy all node_modules/primereact/themes/*/theme.css files into public folder (giving them corresponding theme names). Some theme.css reference fonts - search for "url" in each file, and if present, copy corresponding fonts/ directory too.
I should mention that benefits of example-1 is using minified and bundled CSS files, so themes will be switching faster. If that's important, then follow the above linked tutorial and example-1. Also note that example-2 has very similar setup to example-1 (eject and custom webpack config), but only to copy css files to the right output folder, which can be skipped in favor of copying files by hand once.
There is an even easier way to do this They do explain it a bit in the docs but it isn't as copy-paste in the docs
Here is what I did in my React app:
This is in my index.html file Define an element with an id to reference later in your code, and them also href to the directory where the styles are.
<link id="app-theme" rel="stylesheet" href="/themes/lara-dark-blue/theme.css">
The styles should be copied from the node_modules of prime react Copy the dark and light theme from Lara
cp -r ./node_modules/primereact/resources/themes/lara-light-blue ./public/themes/lara-light-blue
cp -r ./node_modules/primereact/resources/themes/lara-dark-blue ./public/themes/lara-dark-blue
You can also just drag and drop them, but terminal is also nice ;)
Now in your React component, import PrimeReact from the api directory and then use the changeTheme utility function to change from dark to light and vice versa
import PrimeReact from 'primereact/api';
function App() {
const [theme, setTheme] = useState('dark');
const changeMyTheme = () => {
const newTheme = theme === 'dark' ? 'light' : 'dark';
PrimeReact?.changeTheme?.(`lara-${theme}-blue`, `lara-${newTheme}-blue`, 'app-theme', () =>
setTheme(newTheme)
);
};
return (
<div>
<header>
<button
className={`p-2 rounded ${theme === 'dark' ? 'bg-gray-100 text-black' : 'bg-gray-700 text-white'}`}
onClick={() => changeMyTheme()}
>
<span className={`pr-1 pi pi-${theme === 'dark' ? 'sun' : 'moon'}`}></span>
Change Theme
</button>
</header>
</div>
);
}
Here are the docs if you need to reference some more details as well as other themes available https://primereact.org/theming/
reactjs - Use PrimeReact Themes with CSS Modules Enabled in React Application - Stack Overflow
PrimeReact Theme Designer is now free and open source
PrimeReact theme doesn't apply correctly to PrimeReact components
Where to get the visual theme editor?
Videos
I was able to use CSS modules and selectively apply global scoping to PrimeReact's themes by modifying webpack.config as follows below.
Original:
{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
Modified:
{
test: /\.css$/,
//Exclude 3rd party css that needs to be scoped globally from using
//css-loader with modules enabled
exclude: [
path.resolve('node_modules/primereact/resources/primereact.css'),
path.resolve('node_modules/primereact/resources/themes/cupertino/theme.css'),
],
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash_base64:5]'
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
//Additional css-loader configuration
{
test: /\.css$/,
//Inlcude only 3rd party css that needs to be scoped globally to use
//css-loader with modules disabled
include: [
path.resolve('node_modules/primereact/resources/primereact.css'),
path.resolve('node_modules/primereact/resources/themes/cupertino/theme.css'),
],
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
Use the below two npm commands to install the CSS and Style loader:
npm install style-loader - You can add the Version of the loaded if required npm install css-loader
You are not required to change anything else.
» npm install primereact
Hi all,
As part of the PrimeReact roadmap, we're excited to announce that Theme Designer is now open source and free to use.
For more information, visit the documentation.
P.S. We're now working on the new styling engine that utilizes CSS variables instead of SCSS with support for css-in-js and also the new Unstyled mode so that you can just ignore all this and style the components with Tailwind, Bootstrap or similar.
Happy coding!