ufollettu
ufollettu

Reputation: 882

Angular Material Set Theme Colors with Color Picker

I have an app with multiple material themes in theme.scss file:

// Light theme
$light-primary: mat-palette($mat-grey, 200, 500, 300);
$light-accent: mat-palette($mat-brown, 100);
$light-warn: mat-palette($mat-deep-orange, 200);

$light-theme: mat-light-theme($light-primary, $light-accent, $light-warn);

.light-theme {
  @include angular-material-theme($light-theme)
}

// Red theme
$red-primary: mat-palette($mat-red, 700, 500, 300);
$red-accent: mat-palette($mat-amber, 200);
$red-warn: mat-palette($mat-brown, 200);

$red-theme: mat-light-theme($red-primary, $red-accent, $red-warn);

.red-theme {
  @include angular-material-theme($red-theme)
}

if I want to change the theme of the app I can do it by switching existing themes. Now I want to add a feature that let the user to create his custom theme with a color picker that sets $primary, $accent and $warn colors in the app, then post the new created style in the db.

I'm using ngx-color-picker to set colors, but I don't know how to set the custom theme and to use it on user access.

I'm using Angular 6 and material 2

Thanks for help

Upvotes: 2

Views: 3073

Answers (1)

p4r1
p4r1

Reputation: 2650

Since scss styles need to be compiled into css for your browser to understand, dynamically changing the scss doesn't help unless we recompile the styles on-the-fly. While this is an option, I imagine it isn't the most performant for the client to be doing style compilation.

Another way of doing this involves using css variables within the compiled theme css file and changing the value of these variables at run time. For this, you can use your existing theme.scss file, but you'll need to compile it into css using node-sass; from command line, run:

node_modules/.bin/node-sass src/theme.scss -o outputFolder

You could also use one of the prebuilt Material css theme files. Open this css file and do a "find and replace" for all instances of your primary, accent, and warn colors to use css variables, something like var(--primary-color), var(--accent-color), var(--warn-color). These can be a little tricky to find unless you happen to know the hex value of the color you're looking for, so search for .mat-primary, .mat-accent, and .mat-warn and there are your hex values you're looking to replace for the whole file. We next define the default theme colors to use at the root level:

:root {
  --primary-color: purple;
  --accent-color: yellow;
  --warn-color: red;
}

Since we are now going to use this new css file instead of the scss file for our theme, we need to replace the scss file in our angular.json file to point to the new css file. When you get the color values from the database, you can set these variables to the hex values with this:

document.body.style.setProperty('--primary-color', #someColor);
document.body.style.setProperty('--accent-color', #someColor);
document.body.style.setProperty('--warn-color', #someColor);

Here's a stackblitz showing a simple demo of this working.

Upvotes: 6

Related Questions