How can I handle multiple themes in an angular component? - javascript

I'm working on an Angular 9 project where I'm creating two themes and each theme has it's own css output file.
I modified the angular.json file to handle that:
"styles": [
{
"input": "src/styles/themes/light-theme.scss",
"lazy": true,
"bundleName": "light-theme"
},
{
"input": "src/styles/themes/dark-theme.scss",
"lazy": false,
"bundleName": "dark-theme"
}
],
light-theme and dark-theme are my input files, where I'm setting variables like:
$background-color
$button-color
$text-color
etc, etc.
My problem is that I cannot use those variables from each component, because my component won't know what those variables are. I cannot import one or another theme, because I would like to use the values that I declared in the input file.
How should I handle this? Is there any way of "importing" the input file I wrote on my angular.json file?
Thanks!

If you define sass variables in your global styles, you won't be able to access them after when you dynamically change the theme. This is because the dynamically loaded theme will contain css rules only, not sass; besides at run time your components scss has also already compiled to css so there is no more notions of sass variables either way.
What you can do instead is use CSS variables, which have good browser support (apart from IE and opera mini).
So for instance, you can define these variables in your theme files
dark-theme.scss
:root{
--button-background: darkgrey;
--button-color: white;
}
light-theme.scss
:root{
--button-background: lightgrey;
--button-color: black;
}
Then in your component, use these variables
component.scss
button
{
cursor: pointer;
padding: 10px;
border: 0;
color:var(--button-color);
background-color:var(--button-background);
}
Then, when you dynamically load the light theme, it will override the existing variables. If you then dynamically remove light-theme.css, it'll go back to using your dark theme's variables.

Related

dark mode in laravel while using sass

I'm using sass preprocessor on my laravel project.
on all of my stylesheets, i've used css variables for all colors. all of the variables are stored in 'resource/sass/_variables.scss' and imported in the begining of all stylesheet files.
the inside of '_variables.scss' file is something like this:
$primary-background:#1b203d;
$primary-box-color:#2a2b4a;
$primary-border-color: #7277c422;
$secoundary-box-color: #393a66;
$primary-box-shadow: #1a1b2f;
......
and also in my stylesheet i've used variables like this:
#import 'variables';
#sidebar{
background-color: $secoundary-box-color;
border:1px solid $primary-border-color;
// .....
}
now i'm trying to implement dark mode switch using css variables.
I have no idea how to change css variables, consider it that all my stylesheets (with variables) will be compiled and i have no longer access to css variable on the frontend!
you can use css custom properties to assign colors
//_variables.scss
$lightTheme: #fff;
$darkTheme: #000;
//style.css
#import 'variables';
:root {
--theme: #{$lightTheme};
}
body {
background-color: var(--theme);
}
body.dark {
--theme: #{$darkTheme};
}

Postcss-simple-vars is not working properly

I've been at this problem fro quite some time and can't seem to find a solution. Any help would be greatly appreciated. I have created _variables.css file which hold all my CSS variables. I use one of the variables in _global.css on the body tag. However, the styling isn't applied. I have attached screenshots. Thank you. _variables.css. _global.css. styles.css error message
You are using css preprocessors variables so you have to change file extensions to be .scss, also you need to compile your .scss files to .css , check this guide
or you can use css variables with different syntax , just like that
:root {
--main-bg-color: coral;
}
#div1 {
background-color: var(--main-bg-color);
}

Apply CSS theme based on react state

I have a REACT application (bootstrapped with create react app and react-bootstrap) for which I am trying to add option to switch to DARK theme if user enabled this in his settings. I am storing the settings on server and fetching them into properties.
I have a separate stylesheet called dark.css where all my component styles are overriden.
dark.css (example):
#root {
background-color: var(--dark);
color: var(--light)
}
.card {
background-color: var(--dark); // overriding bootstrap styles here
}
I am trying to apply it at the root of my application like this:
componentWillReceiveProps() {
if (this.props.profile && this.props.profile.theme === 'dark') {
require('./styles/dark.css');
}
}
It works great when running the application locally with yarn start. But when I actually build the app using webpack, it works really strange. Part of the new styles are applied and part on, regardless of which theme is selected. For example background is applied from the main theme and ignored in the dark theme but text color is the opposite.
Why is this happening?
It seems that the dark stylesheet is not being applied at all when building the app with webpack, although everything looks correctly when running it with yarn start.
I guess that you have a naming clashes, which overrides your css.
React supports CSS Modules alongside regular stylesheets using the [name].module.css file naming convention.
CSS Modules let you use the same CSS class name in different files without worrying about naming clashes
I solved my issues simply by importing all styled css sheets and then prefixing them like this:
.dark .card {
color: black;
}
.light .card {
color: white;
}
I assign class to the wrapper based on my props:
<div id="root" className={theme}>
// content
</div>
Works like a charm.

How do I make file with variables of all project's colors

I use React.JS to develop a web.I want to define all the colors in one class.
In fact, I am a beginner and I only use colors at CSS files. like this:
.toolbar {
background: primary1;
}
I also want to use them in other type classes that may be needed.
Thank you.
Also, sorry about my English.
in Sass, you can declare all your colors in one file:
//colors.scss
$red: #990000;
$black: #000000;
$white: #ffffff;
And then in any other scss file in your project you can import and use any of the declared colors like this:
//style.scss
#import "path/to/colors.scss";
div {
background: $red;
color: $black;
}
You probably have sass build in support inside your react project, but if not, refer to the docs: https://sass-lang.com/documentation

Using LESS, how do I reference a class in the separate font-awesome .less file?

Background
I am using Twitter Bootstrap LESS source with LessJS
I'm using font-awesome.less (referenced from within Bootstrap.less)
I've removed the icons section from bootstrap so they don't conflict.
I have a site.less file which I also reference from within Bootstrap that contains some site-specific styling.
Goal
I would like to be able to do something along the following lines in my site.css file:
.feedbackItemIconPraise
{
.icon-thumbs-up; //class included in font-awesome.less
color:Green;
}
Problem
When I try the approach above, I get the following error:
This error makes sense; I'm just not sure how best to correct it without creating an additional import of font-awesome.less in my site.less (which I imagine would be its own issue).
To clarify: Per comments below: I have a class name that I'm using from a Knockout viewmodel. (for example, if "Praise" is selected, it will apply the class "FeedbackItemPraise"). If FeedbackItemPraise is selected, I'd like it to apply the .icon-thumbs-up class from font-awesome (which displays the icon via a web font) and then also make the color green.
What I have so far
Bootstrap.less customization (only relevant parts shown):
//Sean's customizations
#import "background.less"; // Background images and colors
#import "font-awesome.less"; // Font Awesome font (SK 2012/09/04)
#import "site.less"; // site-specific LESS
Class within site.less:
.feedbackItemIconPraise
{
.icon-thumbs-up; //class included in font-awesome.less
color:Green;
}
UPDATED
Upon looking at Font-Awesome again, looks like they have now included mixins for the icons. See the following two files.
https://github.com/FortAwesome/Font-Awesome/blob/master/less/variables.less
https://github.com/FortAwesome/Font-Awesome/blob/master/less/mixins.less
Use like:
.feedbackItemIconPraise
{
.icon(#thumbs-up-alt)
color:Green;
}
ORIGINAL
If you look at font-awesome.less you will see that class doesn't exist, it's actually .icon-thumbs-up:before. Unfortunately you can't use pseudo classes as mixins, eg .icon-thumbs-up:before;.
You will need to modify your font-awesome.less file (or just add this class, or just put content: "\f087"; directly where it needs to go) so there is a non :before version:
.icon-thumbs-up:before { content: "\f087"; }
.icon-thumbs-up { content: "\f087"; }
Then apply this concept:
.feedbackItemIconPraise {
font-family: "FontAwesome";
font-size: 90px;
padding-top: 7px;
font-weight: normal;
font-style: normal;
display: inline-block;
text-decoration: inherit;
&:before {
.icon-thumbs-up;
}
}
Seems Font-Awesome icons have to use the :before pseudo for them to show up.
Demo: http://pulse-dev.com/files/stackoverflow/fontawesomeclass/
There may be another solution to this, but I combine my scripts into a single file (automatically) before running it through the LESS compiler. This allows me to define variables and mixins up front that can be used in any of my LESS files.
The online documentation does mention that LESS can include the #import files, making the variables and mixins available. You may need to ensure that you are on the latest version of the compiler and if the import files are organised in a folder structure, you may need to tell the compiler where to search.
var parser = new(less.Parser)({
paths: ['.', './lib'], // Specify search paths for #import directives
filename: 'style.less' // Specify a filename, for better error messages
});

Categories