Reputation: 161
I'm using angular material version 9.2.4.
I want to overwrite the toggle icon to font awesome icon and I found some example is using css code background-image
to overwrite it, but it is possible to use the font-awesome to change the toggle icon?
This is what I want to customize the icon toggle.
Upvotes: 9
Views: 11301
Reputation: 438
In Angular 15 :
you can modify the icon class like this :
::ng-deep .mdc-switch__icons{
display:none!important;
}
this example disable the icons. I spent too long time to find this, I hope it helps some people!
Upvotes: 3
Reputation: 89
You can try this:
Angular >= 15 with SVG
Let's say you have simple slide toggle with custom class in HTML:
<mat-slide-toggle class="icon-slide-toggle"></mat-slide-toggle>
And now you edit path of SVGs in SCSS:
$sun-path: 'm5.64 17l-.71.71a1 1 0 0 0 0 1.41a1 1 0 0 0 1.41 0l.71-.71A1 1 0 0 0 5.64 17ZM5 12a1 1 0 0 0-1-1H3a1 1 0 0 0 0 2h1a1 1 0 0 0 1-1Zm7-7a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v1a1 1 0 0 0 1 1ZM5.64 7.05a1 1 0 0 0 .7.29a1 1 0 0 0 .71-.29a1 1 0 0 0 0-1.41l-.71-.71a1 1 0 0 0-1.41 1.41Zm12 .29a1 1 0 0 0 .7-.29l.71-.71a1 1 0 1 0-1.41-1.41l-.64.71a1 1 0 0 0 0 1.41a1 1 0 0 0 .66.29ZM21 11h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2Zm-9 8a1 1 0 0 0-1 1v1a1 1 0 0 0 2 0v-1a1 1 0 0 0-1-1Zm6.36-2A1 1 0 0 0 17 18.36l.71.71a1 1 0 0 0 1.41 0a1 1 0 0 0 0-1.41ZM12 6.5a5.5 5.5 0 1 0 5.5 5.5A5.51 5.51 0 0 0 12 6.5Zm0 9a3.5 3.5 0 1 1 3.5-3.5a3.5 3.5 0 0 1-3.5 3.5Z';
$moon-path: 'M21.64 13a1 1 0 0 0-1.05-.14a8.05 8.05 0 0 1-3.37.73a8.15 8.15 0 0 1-8.14-8.1a8.59 8.59 0 0 1 .25-2A1 1 0 0 0 8 2.36a10.14 10.14 0 1 0 14 11.69a1 1 0 0 0-.36-1.05Zm-9.5 6.69A8.14 8.14 0 0 1 7.08 5.22v.27a10.15 10.15 0 0 0 10.14 10.14a9.79 9.79 0 0 0 2.1-.22a8.11 8.11 0 0 1-7.18 4.32Z';
::ng-deep .icon-slide-toggle .mdc-switch__icon {
transform: scale(0.8); // This is optional for a better icon fit
// Toggle off
&--off > path {
d: path($sun-path);
}
// Toggle on
&--on > path {
d: path($moon-path);
}
}
Remember to provide proper path for SVGs since their viewBoxes are "0 0 24 24". I recommend this page where you can search for icons you are interested in.
Angular < 15
First, import font awesome either by direct import in your css file or by adding link in head
Secondly, override styles for mat-slide-toggle. I'm using ::ng-deep to make sure it will apply:
::ng-deep .mat-slide-toggle .mat-slide-toggle-thumb:before {
content: "\f185"; // sun icon
font-family: "Font Awesome 5 Free";
font-style: normal;
font-weight: normal;
font-size: 20px;
}
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb:before {
content: "\f186"; // moon icon
font-family: "Font Awesome 5 Free";
font-style: normal;
font-weight: normal;
font-size: 20px;
}
// Disable thumb bg color so the icon is fully visible
::ng-deep .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb {
background-color: transparent !important;
}
::ng-deep .mat-slide-toggle-thumb {
background-color: transparent !important;
}
I hope it helps ^^
Upvotes: 3
Reputation: 6235
This should be doable with some DOM manipulation. This works for Material 15 at the time of writing.
Material 15 (with MDC-based components) now features mat-slide-toggle
with icons (SVG paths in this case). Though it's not possible to swap out the switch icon - instead, we could target them and change the path.d
attribute.
I took icons for dark/light mode from material icons and downloaded it as SVG. https://fonts.google.com/icons?icon.query=dark+mode
I scaled them down by 50% using an online SVG editor: https://aydos.com/svgedit/ Icon needed to be scaled down to fit the switch.
Using @ViewChild
to find and query the right SVG targets and replace their attributes. I replaced the default attribute d
on path
with the scaled-down version. We need to read the element as ElementRef using { read: ElementRef }
to access nativeElement
.
Though using querySelector
is not optimal - perhaps there are better ways.
html:
<mat-slide-toggle #darkModeSwitch></mat-slide-toggle>
ts:
@Component({
selector: 'slide-toggle-overview-example',
templateUrl: 'slide-toggle-overview-example.html',
})
export class SlideToggleOverviewExample implements AfterViewInit {
@ViewChild('darkModeSwitch', { read: ElementRef }) element: ElementRef | undefined;
sun = 'M12 15.5q1.45 0 2.475-1.025Q15.5 13.45 15.5 12q0-1.45-1.025-2.475Q13.45 8.5 12 8.5q-1.45 0-2.475 1.025Q8.5 10.55 8.5 12q0 1.45 1.025 2.475Q10.55 15.5 12 15.5Zm0 1.5q-2.075 0-3.537-1.463T7 12q0-2.075 1.463-3.537T12 7q2.075 0 3.537 1.463T17 12q0 2.075-1.463 3.537T12 17ZM1.75 12.75q-.325 0-.538-.213Q1 12.325 1 12q0-.325.212-.537Q1.425 11.25 1.75 11.25h2.5q.325 0 .537.213Q5 11.675 5 12q0 .325-.213.537-.213.213-.537.213Zm18 0q-.325 0-.538-.213Q19 12.325 19 12q0-.325.212-.537.212-.213.538-.213h2.5q.325 0 .538.213Q23 11.675 23 12q0 .325-.212.537-.212.213-.538.213ZM12 5q-.325 0-.537-.213Q11.25 4.575 11.25 4.25v-2.5q0-.325.213-.538Q11.675 1 12 1q.325 0 .537.212 .213.212 .213.538v2.5q0 .325-.213.537Q12.325 5 12 5Zm0 18q-.325 0-.537-.212-.213-.212-.213-.538v-2.5q0-.325.213-.538Q11.675 19 12 19q.325 0 .537.212 .213.212 .213.538v2.5q0 .325-.213.538Q12.325 23 12 23ZM6 7.05l-1.425-1.4q-.225-.225-.213-.537.013-.312.213-.537.225-.225.537-.225t.537.225L7.05 6q.2.225 .2.525 0 .3-.2.5-.2.225-.513.225-.312 0-.537-.2Zm12.35 12.375L16.95 18q-.2-.225-.2-.538t.225-.512q.2-.225.5-.225t.525.225l1.425 1.4q.225.225 .212.538-.012.313-.212.538-.225.225-.538.225t-.538-.225ZM16.95 7.05q-.225-.225-.225-.525 0-.3.225-.525l1.4-1.425q.225-.225.538-.213.313 .013.538 .213.225 .225.225 .537t-.225.537L18 7.05q-.2.2-.512.2-.312 0-.538-.2ZM4.575 19.425q-.225-.225-.225-.538t.225-.538L6 16.95q.225-.225.525-.225.3 0 .525.225 .225.225 .225.525 0 .3-.225.525l-1.4 1.425q-.225.225-.537.212-.312-.012-.537-.212ZM12 12Z'
moon ='M12 21q-3.75 0-6.375-2.625T3 12q0-3.75 2.625-6.375T12 3q.2 0 .425.013 .225.013 .575.038-.9.8-1.4 1.975-.5 1.175-.5 2.475 0 2.25 1.575 3.825Q14.25 12.9 16.5 12.9q1.3 0 2.475-.463T20.95 11.15q.025.3 .038.488Q21 11.825 21 12q0 3.75-2.625 6.375T12 21Zm0-1.5q2.725 0 4.75-1.687t2.525-3.963q-.625.275-1.337.412Q17.225 14.4 16.5 14.4q-2.875 0-4.887-2.013T9.6 7.5q0-.6.125-1.287.125-.687.45-1.562-2.45.675-4.062 2.738Q4.5 9.45 4.5 12q0 3.125 2.188 5.313T12 19.5Zm-.1-7.425Z'
ngAfterViewInit() {
if (this.element){
this.element.nativeElement.querySelector('.mdc-switch__icon--on').firstChild.setAttribute('d', this.moon);
this.element.nativeElement.querySelector('.mdc-switch__icon--off').firstChild.setAttribute('d', this.sun);
}
}
}
Working example: https://stackblitz.com/edit/angular-3fkfgv?file=src%2Fapp%2Fslide-toggle-overview-example.ts
html
<mat-slide-toggle
#darkModeSwitch
(change)="changeTheme()"
[checked]="checked"
[disabled]="disabled">
</mat-slide-toggle>
ts
import {AfterViewInit, Component, ElementRef, Renderer2, ViewChild} from '@angular/core';
@Component({
selector: 'slide-toggle-overview-example',
templateUrl: 'slide-toggle-overview-example.html',
styleUrls: ['slide-toggle-overview-example.css'],
})
export class SlideToggleOverviewExample implements AfterViewInit {
constructor(private renderer: Renderer2) {}
@ViewChild('darkModeSwitch', { read: ElementRef }) element: ElementRef | undefined;
checked = false;
disabled = false;
ngAfterViewInit() {
this.setIcon();
}
setIcon() {
if (this.element) {
const targetSpan: HTMLElement = this.element.nativeElement.querySelector('.mat-slide-toggle-thumb');
while (targetSpan.firstChild) {
targetSpan.firstChild.remove();
}
const elem = this.renderer.createElement('mat-icon');
const icon = this.checked ? 'dark_mode' : 'light_mode';
elem.setAttribute('class', 'mat-icon notranslate material-icons mat-icon-no-color light-mode-switch-icon');
elem.textContent = icon
targetSpan.appendChild(elem);
}
}
changeTheme() {
this.checked = !this.checked;
console.log('I am now ', this.checked);
this.setIcon();
}
}
Example: https://stackblitz.com/edit/angular-nnj29e?file=app%2Fslide-toggle-overview-example.ts
Upvotes: 13
Reputation: 17610
Demo After import fontawesome in project do it in style.css
.mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb:before {
content: "\f00c";
font: normal normal normal 14px/1 FontAwesome;
}
Upvotes: 5
Reputation: 1631
Unfortunately, mostly it is too hard, to override look and layout in Angular Material, even changing the styles is sometimes harsh. No currently there is no way to change the icon officially
Upvotes: 0