The introduction of Tailwind appears to have broken my Angular Material custom theme file

Viewed 800

Hello All – my colleagues and I have been struggling with this one, so any help would be greatly appreciated!

Our project uses angular material and scss (including a custom material theme). We would like to add tailwind to this so that we can streamline as much of the styling as possible.

We know this is possible, as I was able to achieve it in my demo to the rest of the team; whereby I created a new project, set it up with scss and angular material, ran a custom theme, and then added tailwind to it, following the steps outlined here. This runs fine.

However, since then, I have failed in all attempts to apply tailwind to our existing project. Following the steps I took before (as in article), I am presented with the following errors when attempting to compile:

  1. ERROR in Cannot read property 'flags' of undefined

  2. ERROR in ./src/styles/jml-theme.scss (C:/C4/C4UI_Feature/node_modules/css-loader/dist/cjs.js??ref--13-1!C:/C4/C4UI_Feature/node_modules/@angular-builders/custom-webpack/node_modules/postcss-loader/src??embedded!C:/C4/C4UI_Feature/node_modules/resolve-url-loader??ref--13-3!C:/C4/C4UI_Feature/node_modules/@angular-builders/custom-webpack/node_modules/sass-loader/dist/cjs.js??ref--13-4!C:/C4/C4UI_Feature/node_modules/postcss-loader/dist/cjs.js??ref--17!./src/styles/jml-theme.scss)

SassError: Plain CSS functions don't support keyword arguments.
   ╷
30 │   $fontConfig: mat-typography-config(
   │ ┌──────────────^
31 │ │   $font-family: 'Lato, "Helvetica Neue", sans-serif',
32 │ │   $display-4: mat-typography-level(112px, 112px, 300),
33 │ │   $display-3: mat-typography-level(56px, 56px, 400),
34 │ │   $display-2: mat-typography-level(45px, 48px, 400),
35 │ │   $display-1: mat-typography-level(34px, 40px, 400),
36 │ │   $headline: mat-typography-level(32px, 48px, 500),
37 │ │   $title: mat-typography-level(24px, 33.6px, 400),
38 │ │   $subheading-2: mat-typography-level(16px, 22.4px, 500),
39 │ │   $subheading-1: mat-typography-level(16px, 22.4px, 400),
40 │ │   $body-1: mat-typography-level(16px, 22.4px, 400),
41 │ │   $body-2: mat-typography-level(16px, 22.4px, 500),
42 │ │   $button: mat-typography-level(14px, 14px, 500),
43 │ │   $caption: mat-typography-level(14px, 19.6px, 400),
44 │ │   $input: mat-typography-level(16px, 1, 400),
45 │ │ );
   │ └─^
   ╵
  projects\c4ui\src\styles\jml-theme.scss 30:14  root stylesheet

I find this odd, given that mat-typography-config is an scss mixin, and not a function. Removing this mixin and the code which subsequently relies upon it further down, namely:

@include mat-core($fontConfig);

Returns the first error again, followed by:

Module build failed (from C:/C4/C4UI_Feature/node_modules/@angular-builders/custom-webpack/node_modules/sass-loader/dist/cjs.js):
SassError: (main: #ffffff, lighter: #ffffff, darker: #ffffff, 200: #ffffff, contrast: (main: rgba(88, 88, 87, 0.87), lighter: rgba(88, 88, 87, 0.87), darker: rgba(88, 88, 87, 0.87))) isn't a valid CSS value.      
    ╷
235 │ $theme-primary: mat-palette($mat-primary, main, lighter, darker);
    │                             ^^^^^^^^^^^^
    ╵
  projects\c4ui\src\styles\jml-theme.scss 235:29  root stylesheet

As such, it is now refusing to recognise the following (defined in the line above the declaration of $theme-primary):

$mat-primary: (
  main: colours.$base-white,
  lighter: colours.$base-white,
  darker: colours.$base-white,
  200: colours.$base-white,
  // For slide toggle,
  contrast:
    (
      main: $dark-primary-text,
      lighter: $dark-primary-text,
      darker: $dark-primary-text,
    ),
);

For clarity, below is the entirety of the theme file:

/**
* Generated theme by Material Theme Generator
* https://materialtheme.arcsine.dev
*/
// @use "_colours.scss";
@use "colours";
@use "../../../../node_modules/@angular/material/_theming.scss";
// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.

// Fonts
// @import url("https://fonts.googleapis.com/icon?family=Material+Icons+Outlined");
// @import url("https://fonts.googleapis.com/css?family=Lato:300,400,500");

// @use "sass:map";

$fontConfig: mat-typography-config(
  $font-family: 'Lato, "Helvetica Neue", sans-serif',
  $display-4: mat-typography-level(112px, 112px, 300),
  $display-3: mat-typography-level(56px, 56px, 400),
  $display-2: mat-typography-level(45px, 48px, 400),
  $display-1: mat-typography-level(34px, 40px, 400),
  $headline: mat-typography-level(32px, 48px, 500),
  $title: mat-typography-level(24px, 33.6px, 400),
  $subheading-2: mat-typography-level(16px, 22.4px, 500),
  $subheading-1: mat-typography-level(16px, 22.4px, 400),
  $body-1: mat-typography-level(16px, 22.4px, 400),
  $body-2: mat-typography-level(16px, 22.4px, 500),
  $button: mat-typography-level(14px, 14px, 500),
  $caption: mat-typography-level(14px, 19.6px, 400),
  $input: mat-typography-level(16px, 1, 400),
);

// Foreground Elements

// Light Theme Text
$dark-text: colours.$greyish-brown;
$dark-primary-text: rgba($dark-text, 0.87);
$dark-accent-text: rgba($dark-primary-text, 0.54);
$dark-disabled-text: rgba($dark-primary-text, 0.38);
$dark-dividers: rgba($dark-primary-text, 0.12);
$dark-focused: rgba($dark-primary-text, 0.12);

$mat-light-theme-foreground: (
  base: black,
  divider: $dark-dividers,
  dividers: $dark-dividers,
  disabled: $dark-disabled-text,
  disabled-button: rgba($dark-text, 0.26),
  disabled-text: $dark-disabled-text,
  elevation: black,
  secondary-text: $dark-accent-text,
  hint-text: $dark-disabled-text,
  accent-text: $dark-accent-text,
  icon: $dark-accent-text,
  icons: $dark-accent-text,
  text: $dark-primary-text,
  slider-min: $dark-primary-text,
  slider-off: rgba($dark-text, 0.26),
  slider-off-active: $dark-disabled-text,
);

// Dark Theme text
$light-text: colours.$base-white;
$light-primary-text: $light-text;
$light-accent-text: rgba($light-primary-text, 0.7);
$light-disabled-text: rgba($light-primary-text, 0.5);
$light-dividers: rgba($light-primary-text, 0.12);
$light-focused: rgba($light-primary-text, 0.12);

$mat-dark-theme-foreground: (
  base: $light-text,
  divider: $light-dividers,
  dividers: $light-dividers,
  disabled: $light-disabled-text,
  disabled-button: rgba($light-text, 0.3),
  disabled-text: $light-disabled-text,
  elevation: black,
  hint-text: $light-disabled-text,
  secondary-text: $light-accent-text,
  accent-text: $light-accent-text,
  icon: $light-text,
  icons: $light-text,
  text: $light-text,
  slider-min: $light-text,
  slider-off: rgba($light-text, 0.3),
  slider-off-active: rgba($light-text, 0.3),
);

// Background config
// Light bg
$light-background: colours.$ice-blue;
$light-bg-darker-5: darken($light-background, 5%);
$light-bg-darker-10: darken($light-background, 10%);
$light-bg-darker-20: darken($light-background, 20%);
$light-bg-darker-30: darken($light-background, 30%);
$light-bg-lighter-5: lighten($light-background, 5%);
$dark-bg-tooltip: lighten(colours.$fill-primary-dark-blue, 20%);
$dark-bg-alpha-4: rgba(colours.$fill-primary-dark-blue, 0.04);
$dark-bg-alpha-12: rgba(colours.$fill-primary-dark-blue, 0.12);

$mat-light-theme-background: (
  background: $light-background,
  status-bar: $light-bg-darker-20,
  app-bar: $light-bg-darker-5,
  hover: $dark-bg-alpha-4,
  card: $light-bg-lighter-5,
  dialog: $light-bg-lighter-5,
  tooltip: $dark-bg-tooltip,
  disabled-button: $dark-bg-alpha-12,
  raised-button: $light-bg-lighter-5,
  focused-button: $dark-focused,
  selected-button: $light-bg-darker-20,
  selected-disabled-button: $light-bg-darker-30,
  disabled-button-toggle: $light-bg-darker-10,
  unselected-chip: $light-bg-darker-10,
  disabled-list-option: $light-bg-darker-10,
);

// Dark bg
$dark-background: colours.$fill-primary-dark-blue;
$dark-bg-lighter-5: lighten($dark-background, 5%);
$dark-bg-lighter-10: lighten($dark-background, 10%);
$dark-bg-lighter-20: lighten($dark-background, 20%);
$dark-bg-lighter-30: lighten($dark-background, 30%);
$light-bg-alpha-4: rgba(colours.$ice-blue, 0.04);
$light-bg-alpha-12: rgba(colours.$ice-blue, 0.12);

// Background palette for dark themes.
$mat-dark-theme-background: (
  background: $dark-background,
  status-bar: $dark-bg-lighter-20,
  app-bar: $dark-bg-lighter-5,
  hover: $light-bg-alpha-4,
  card: $dark-bg-lighter-5,
  dialog: $dark-bg-lighter-5,
  tooltip: $dark-bg-lighter-20,
  disabled-button: $light-bg-alpha-12,
  raised-button: $dark-bg-lighter-5,
  focused-button: $light-focused,
  selected-button: $dark-bg-lighter-20,
  selected-disabled-button: $dark-bg-lighter-30,
  disabled-button-toggle: $dark-bg-lighter-10,
  unselected-chip: $dark-bg-lighter-20,
  disabled-list-option: $dark-bg-lighter-10,
);

// Compute font config
@include mat-core($fontConfig);

// Theme Config

body {
  --primary-color: colours.$base-white;
  --primary-lighter-color: colours.$base-white;
  --primary-darker-color: colours.$base-white;
  --text-primary-color: #{$dark-primary-text};
  --text-primary-lighter-color: #{$dark-primary-text};
  --text-primary-darker-color: #{$dark-primary-text};
}

$mat-primary: (
  main: colours.$base-white,
  lighter: colours.$base-white,
  darker: colours.$base-white,
  200: colours.$base-white,
  // For slide toggle,
  contrast:
    (
      main: $dark-primary-text,
      lighter: $dark-primary-text,
      darker: $dark-primary-text,
    ),
);
$theme-primary: mat-palette($mat-primary, main, lighter, darker);

body {
  --accent-color: colours.$fill-primary-dark-blue;
  --accent-lighter-color: colours.$aqua-blue;
  --accent-darker-color: colours.$fill-secondary-chronicle-blue;
  --text-accent-color: #{$light-primary-text};
  --text-accent-lighter-color: #{$dark-primary-text};
  --text-accent-darker-color: #{$light-primary-text};
}

$mat-accent: (
  main:colours.$fill-primary-dark-blue,
  lighter:colours.$aqua-blue,
  darker: colours.$fill-secondary-chronicle-blue,
  200:colours.$fill-secondary-chronicle-blue,
  // For slide toggle,
  contrast:
    (
      main: $light-primary-text,
      lighter: $dark-primary-text,
      darker: $light-primary-text,
    ),
);
$theme-accent: mat-palette($mat-accent, main, lighter, darker);

body {
  --warn-color: colours.$fill-secondary-chronicle-pink;
  --warn-lighter-color:colours.$twilight;
  --warn-darker-color: colours.$cherry;
  --text-warn-color: #{$light-primary-text};
  --text-warn-lighter-color: #{$dark-primary-text};
  --text-warn-darker-color: #{$light-primary-text};
}

$mat-warn: (
  main:colours.$fill-secondary-chronicle-pink,
  lighter: colours.$twilight,
  darker:  colours.$cherry,
  200: colours.$fill-secondary-chronicle-pink,
  // For slide toggle,
  contrast:
    (
      main: $light-primary-text,
      lighter: $dark-primary-text,
      darker: $light-primary-text,
    ),
);
$theme-warn: mat-palette($mat-warn, main, lighter, darker);

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

// Theme Init
@include angular-material-theme($theme);

.theme-alternate {
  @include angular-material-theme($altTheme);
}

// Specific component overrides, pieces that are not in line with the general theming

// Handle buttons appropriately, with respect to line-height
.mat-raised-button,
.mat-stroked-button,
.mat-flat-button {
  padding: 0 1.15em;
  margin: 0 0.65em;
  min-width: 3em;
  line-height: 36.4px;
}

.mat-standard-chip {
  padding: 0.5em 0.85em;
  min-height: 2.5em;
}

.material-icons {
  font-size: 24px;
  font-family: "Material Icons Outlined", "Material Icons";
  .mat-badge-content {
    font-family: "Lato";
  };
  color: map.get($mat-accent, "main");
}

My webpack and tailwind config files are located at the root of the project, and are set up, respectively, as follows:

const merge = require('webpack-merge');

module.exports = (config) => {
    const isProd = config.mode === "production";
    const tailwindConfig = require("./tailwind.config.js")(isProd);

    return merge(config, {
        module: {
            rules: [
                {
                    test: /\.scss$/,
                    loader: 'postcss-loader',
                    options: {
                        postcssOptions: {
                            ident: 'postcss',
                            syntax: 'postcss-scss',
                            plugins: [
                                require('postcss-import'),
                                require('tailwindcss')(tailwindConfig),
                                require('autoprefixer'),
                            ]
                        }
                    }
                }
            ]
        }
    });
};
module.exports = (isProd) => ({
  corePlugins: {
    preflight: false,
  },
  prefix: '',
  future: {
    removeDeprecatedGapUtilities: true,
    purgeLayersByDefault: true
  },
  purge: {
    enabled: isProd,
    content: ['**/*.html', '**/*.ts']
  },
  theme: {
    extend: {
      colors: {
        'jml-greyish-brown': 'rgba(88, 88, 87, 0.1)',
        'jml-ice-blue': '#e5eef1',
        'jml-fill-primary-dark-blue': '#015c75',
        'jml-fill-secondary-bright-green': '#01753d',
      }
    }
  }
});
0 Answers
Related