ChrisK
ChrisK

Reputation: 21

Angular Material prebuilt themes not working properly

i have spent a lot of time trying to figure out Angular Material Themes. I startet with simply importing a prebuilt one but i am already having problems. The Theming doesnt seem to apply to all the Tags. In my understanding a "prebuilt theme" should provide default styling for each and every one of the material components. That doesnt seem to be the case. Specifically the mat-list components are invisible (background- and font color are both white)

styles.scss:

@import '@angular/material/prebuilt-themes/deeppurple-amber.css';

@import '../node_modules/@angular/material/theming';

$anms-black-primary: mat-palette($mat-grey, 700, 300, 900);
$anms-black-accent: mat-palette($mat-blue-grey, 400);
$anms-black-warn: mat-palette($mat-red, 500);

$anms-black-theme: mat-dark-theme(
    $anms-black-primary,
    $anms-black-accent,
    $anms-black-warn
);
@include angular-material-theme($anms-black-theme);
.deeppurple-amber {
  @include angular-material-theme($anms-black-theme);
}

everything past the first input is copied from How are Angular Prebuilt Themes generated? . with this most components in my project are at least styled in some way. However, notably the mat-list i have is still invisible :

  <h1>Start Page</h1>
  <!-- <mat-icon svgIcon="gg-add"></mat-icon>
  <mat-icon svgIcon="gg-push-chevron-down"></mat-icon> -->
  <mat-list role="list">
    <mat-list-item role="listitem" *ngFor="let item of data">
      <div matListItemTitle><span style="font-weight: bold;">{{ item.name }}: </span> </div>
      <div matListItemLine>{{ item.number }} {{ item.unit }}</div>

      </mat-list-item>
  </mat-list>

maybe the mat-list need to be wrapped into something? The docs wont tell.

I would like to know why my mat-list arent properly styled and what is the minimum effort to have a prebuilt theme properly put in so that the styles apply to all the material components.

Also, why do i need to set a black colour theme in the styles.scss when im already importing a prebuilt theme? Is a prebuilt theme even supposed to work the way that i expect it to (import it and have it work with no further css).

I included a prebuilt theme into the styles.scss and i expected all material components to be styled properly.

Upvotes: 2

Views: 3503

Answers (3)

andymel
andymel

Reputation: 5706

If you have that problem with an angular elements based microfrontend with ViewEncapsulation.ShadowDom set you maybe have the same problem as I had:

Why it did not work
My dive into the code showed that

  • at runtime the used material theme is added as <style> tag inside of the shadow-root
  • in the prebuilt themes the variables that style the components are defined for the <html> element of the DOM. In a normal SPA everything is inside that html element and so everything has access to those variables

As the shadow DOM is a border between the CSS of the host page and the CSS of the Microfrontend/Webcomponent, everything inside that shadow-root does not have access to css outside of the shadow-root (defining something for the <html> tag in a <style> tag inside the shadow-root does not work).

My Solution
I added a div in the root component of my app, that wraps everything.

<div id="mfe-container">
   ...everything that was in the app.component.html before...
</div>

Instead of including the theme in the html element, I include it in that wrapper element in my styles.scss

@use '@angular/material' as mat;

// my custom theme file
@use './m3-theme';

// The core mixin must be included exactly once for your application, even if you define multiple themes. 
// Including the core mixin multiple times will result in duplicate CSS in your application.
// https://material.angular.io/guide/theming#the-core-mixin
@include mat.core();

#mfe-container {
  @include mat.all-component-themes(m3-theme.$light-theme);
}

Upvotes: 1

BAN
BAN

Reputation: 11

I had a similar issue with a <mat-tab>, the prebuilt themes make the text white with a white background.

I couldn't use the import for the theming stylesheet I found in a guide (@import '~@angular/material/theming';), but @use '@angular/material' as mat; worked for me.

Example of code that finally runs

@use '@angular/material' as mat;

$my-primary: mat.define-palette(mat.$indigo-palette, 500);
$my-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
$my-warn: mat.define-palette(mat.$red-palette);

$my-theme: mat.define-light-theme((
  color: (
    primary: $my-primary,
    accent: $my-accent,
    warn: $my-warn,
  )
));

@include mat.all-component-themes($my-theme);

Note: filename is theme.scss. It is listed under "styles" in angular.json.

Package.json:

  {
  "name": "task-tracker-app",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^17.1.0",
    "@angular/cdk": "^17.1.0",
    "@angular/common": "^17.1.0",
    "@angular/compiler": "^17.1.0",
    "@angular/core": "^17.1.0",
    "@angular/forms": "^17.1.0",
    "@angular/material": "^17.1.0",
    "@angular/platform-browser": "^17.1.0",
    "@angular/platform-browser-dynamic": "^17.1.0",
    "@angular/router": "^17.1.0",
    "rxjs": "~7.8.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.14.3"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^17.1.0",
    "@angular/cli": "^17.1.0",
    "@angular/compiler-cli": "^17.1.0",
    "@types/jasmine": "~5.1.0",
    "jasmine-core": "~5.1.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.2.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "~2.1.0",
    "typescript": "~5.3.2"
  }
  }

Hope you find something that works, best of luck!

Upvotes: 1

Parth M. Dave
Parth M. Dave

Reputation: 1163

As of me i think you are forgot to import module in you app.module file. I have created one module where i have define all module of Angular material that i want to access as below:

import { NgModule } from '@angular/core';
import { LayoutModule } from '@angular/cdk/layout';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatListModule } from '@angular/material/list';
import { MatMenuModule } from '@angular/material/menu';
import { MatSelectModule } from '@angular/material/select';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatCheckboxModule } from '@angular/material/checkbox';
import {MatBadgeModule} from '@angular/material/badge';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatTableModule } from '@angular/material/table';
import { MatCardModule } from '@angular/material/card';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatTabsModule } from '@angular/material/tabs';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {MatRadioModule} from '@angular/material/radio';
import {MatChipsModule} from '@angular/material/chips';
import {ScrollingModule} from '@angular/cdk/scrolling';
const UI_MODULES = [
  MatDialogModule,
  MatListModule,
  MatTooltipModule,
  MatButtonModule,
  MatFormFieldModule,
  MatSelectModule,
  MatInputModule,
  MatMenuModule,
  MatIconModule,
  MatSnackBarModule,
  MatDatepickerModule,
  MatAutocompleteModule,
  MatToolbarModule,
  MatSidenavModule,
  MatTableModule,
  MatCheckboxModule,
  MatCardModule,
  LayoutModule,
  MatGridListModule,
  MatExpansionModule,
  MatTabsModule,
  MatButtonToggleModule,
  MatPaginatorModule,
  MatSortModule,
  MatSlideToggleModule,
  MatRadioModule,
  MatChipsModule,
  ScrollingModule,
  MatBadgeModule,
  
];
@NgModule({
  declarations: [],
  imports: UI_MODULES, exports: UI_MODULES
})
export class AppMaterialUiModule { }

Import that module in App.module inside import part.:

imports:[AppMaterialUiModule,]

Upvotes: 0

Related Questions