0

I have an Angular 11 application that we build in several configurations specific to a customer. I am trying to implement a sensible theming pattern to allow each dist of the app to have it's own colour scheme relevant to the customers branding.

So far I have a styles folder that contains the following scss files for each customer: -

a palette.scss file

$custom-primary: (
    50: #e3e7ec,
    100: #b9c4d0,
    200: #8a9db1,
    300: #5b7691,
    400: #37587a,
    500: #143b62,
    600: #12355a,
    700: #0e2d50,
    800: #0b2646,
    900: #061934,
    A100: #6d9dff,
    A200: #3a7bff,
    A400: #0759ff,
    A700: #004eec,
    contrast: (
        50: $black-87-opacity,
        100: $black-87-opacity,
        200: $black-87-opacity,
        300: $black-87-opacity,
        400: $black-87-opacity,
        500: white,
        600: white,
        700: white,
        800: $white-87-opacity,
        900: $white-87-opacity,
        A100: $black-87-opacity,
        A200: white,
        A400: white,
        A700: white,
    ),
);

$custom-accent: (
    50: #eaf3fa,
    100: #cae0f2,
    200: #a7cce9,
    300: #84b7e0,
    400: #69a7da,
    500: #4f98d3,
    600: #4890ce,
    700: #3f85c8,
    800: #367bc2,
    900: #266ab7,
    A100: #f5f9ff,
    A200: #c2ddff,
    A400: #8fc0ff,
    A700: #75b2ff,
    contrast: (
        50: $black-87-opacity,
        100: $black-87-opacity,
        200: $black-87-opacity,
        300: $black-87-opacity,
        400: $black-87-opacity,
        500: white,
        600: white,
        700: white,
        800: $white-87-opacity,
        900: $white-87-opacity,
        A100: $black-87-opacity,
        A200: white,
        A400: white,
        A700: white,
    ),
);

$custom-warn: (
    50: #ffe0e0,
    100: #ffb3b3,
    200: #ff8080,
    300: #ff4d4d,
    400: #ff2626,
    500: #ff0000,
    600: #ff0000,
    700: #ff0000,
    800: #ff0000,
    900: #ff0000,
    A100: #ffffff,
    A200: #fff2f2,
    A400: #ffbfbf,
    A700: #ffa6a6,
    contrast: (
        50: $black-87-opacity,
        100: $black-87-opacity,
        200: $black-87-opacity,
        300: $black-87-opacity,
        400: $black-87-opacity,
        500: white,
        600: white,
        700: white,
        800: $white-87-opacity,
        900: $white-87-opacity,
        A100: $black-87-opacity,
        A200: white,
        A400: white,
        A700: white,
    ),
);

and then there is a theme.scss file

@import "~@angular/material/theming";
@import "./cchub-palette.scss";

@include mat-core();

$cchub-app-primary: mat-palette($custom-primary);
$cchub-app-accent: mat-palette($custom-accent, A200, A100, A400);
$cchub-app-warn: mat-palette($custom-warn);

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

@include angular-material-theme($cchub-app-theme);

$primary: mat-color($cchub-app-primary);
$accent: mat-color($cchub-app-accent);
$warn: mat-color($cchub-app-warn);

$grey-text: rgba(0, 0, 0, 0.45);
$border: rgba(0, 0, 0, 0.25);
$light-grey: rgba(0, 0, 0, 0.1);

I also have a standard styles.scss file that holds all of my structural styles and I then created a variables.scss to allow access to the theme colours within each component

@import "~@angular/material/theming";

@mixin material-theme($theme) {
    $primary-palette: map-get($theme, primary);
    $accent-palette: map-get($theme, accent);
    $warn-palette: map-get($theme, warn);

     $primary: mat-color($cchub-app-primary);
     $accent: mat-color($cchub-app-accent);
     $warn: mat-color($cchub-app-warn);
}

$grey-text: rgba(0, 0, 0, 0.45);
$border: rgba(0, 0, 0, 0.25);
$light-grey: rgba(0, 0, 0, 0.1);

I then use the styles: [] entry within the angular.json file to include the relevant brand specific files for each customer. unfortunately I cannot access the $primary, $accent and $warn colours from the variables.scss file because they are scoped inside the @mixin.

I'm trying to avoid having @mixin statements inside every component just because I want to access the current $primary colour or such.

Any ideas?

1 Answer 1

1

Going by this approach this will not only make your application heaver but also it will increase complexity when you wanted to introduce some new color/variable only for one theme but not for the other. This will hamper the scalability of the application.

A better way would be creating two different files such as index-dark-theme.scss or index-light-theme.scss define all the related properties into respective file such as.

Inside your index-dark-theme.scss or index-light-theme-scss file you can import something like this

  • @import '~/<node_module imports>' eg(bootstrap);

  • @import 'varible-.scss';

  • @import 'utils.scss';

  • @import 'component-one-(theme).scss';

  • .... (Define all your same theme components here)

Structure for component-one component will look something like this

component-one

  • component-one.ts
  • component-one.html
  • component-one.scss
  • component-one-dark.scss
  • component-one-light-scss

In component-one.scss will hold all the css properties with variable assigned to each css property eg:

    $container-padding-left;
    $container-maring-right;
    $container-background;

.container {
 background: $container-background;
 padding-left: $container-padding-left;
 margin-right: $container-margin-right;
}

In component-one-(theme).scss theme file you just need to assign the values to variables defined by importing ```component-one.scss```` into your theme file.

@import 'component-one.scss';

    $container-padding-left : 20px !default;
    $container-margin-right: 50px  !default;
    $container-background: $bg-black-400 !default;

If you don't want to give any value to variable you can assign null so that that particular property will not render in css itself. eg: container-margin-right: null

Inside your utils.scss file you can define your generic functions or mixins and then you can use by both the themes. Just passing a different value form a particular theme file should work fine.

If incase in near future you wanted to introduce a new theme such as blue theme same pattern can be followed.

Depending on selection of theme you have to just replace index-<theme-name>.scss dynamically. Rest everything will work fine :).

By this approach it will become more dynamic as and will improve the scalability of your application.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.