refactor: migrate to material symbols icon set

This commit is contained in:
Thea Schöbl
2022-08-19 11:48:34 +00:00
parent f3cf3b30e3
commit 68734bfe21
2097 changed files with 26045 additions and 18101 deletions

View File

@@ -0,0 +1,145 @@
/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {
ComponentRef,
Directive,
ElementRef,
OnDestroy,
OnInit,
ViewContainerRef,
} from '@angular/core';
import {IonIcon} from '@ionic/angular';
import {IonIconDirective} from './ion-icon.directive';
export type IconData = Omit<
Partial<IonIconDirective>,
| 'ngOnChanges'
| 'ngOnInit'
| 'viewContainerRef'
| 'ngOnDestroy'
| 'element'
| 'ionIcon'
| 'disableProperty'
>;
/**
* A utility class to replace ion-icons in other ionic components.
*/
@Directive()
export abstract class IconReplacer implements OnInit, OnDestroy {
private mutationObserver: MutationObserver;
protected slotName = 'sc-icon';
/**
* The host element
*
* This will be either element.nativeElement.shadowRoot or element.nativeElement
* depending on the iconDomLocation
*/
protected host: HTMLElement;
/**
* @param element The host element
* @param viewContainerRef The view container ref
* @param iconDomLocation If the icon is placed inside the shadow dom or not
* @protected
*/
protected constructor(
private readonly element: ElementRef,
private readonly viewContainerRef: ViewContainerRef,
private readonly iconDomLocation: 'shadow' | 'light',
) {}
/**
* Replace the icons here
*/
abstract replace(): void;
/**
* If any additional work needs to be done, this
* is called during ngOnInit
*/
init() {
// noop
}
/**
* If you need to do cleanup, this method is called during ngOnDestroy
*/
destroy() {
// noop
}
ngOnInit() {
this.host =
this.iconDomLocation === 'shadow'
? this.element.nativeElement.shadowRoot
: this.element.nativeElement;
this.init();
this.mutationObserver = new MutationObserver(() => this.replace());
this.mutationObserver.observe(this.host, {
childList: true,
});
}
replaceIcon(parent: HTMLElement | null, iconData: IconData) {
if (!parent) return;
const icon = parent.querySelector('ion-icon');
if (!icon) return;
const scIcon = this.createIcon(iconData);
// @ts-expect-error can be spread
scIcon.location.nativeElement.classList.add(...icon.classList);
if (this.iconDomLocation === 'shadow') {
// shadow dom needs to utilize slotting, to put it outside
// the shadow dom, otherwise it won't receive any css data
const slot = document.createElement('slot');
slot.name = this.slotName;
icon.replaceWith(slot);
scIcon.location.nativeElement.slot = this.slotName;
this.element.nativeElement.append(scIcon.location.nativeElement);
} else {
icon.replaceWith(scIcon.location.nativeElement);
}
}
private createIcon(iconData: IconData): ComponentRef<IonIcon> {
const ionIcon = this.viewContainerRef.createComponent(IonIcon, {});
const iconDirective = new IonIconDirective(
ionIcon.location,
this.viewContainerRef,
ionIcon.instance,
);
for (const key in iconData) {
// @ts-expect-error type mismatch
iconDirective[key] = iconData[key];
}
iconDirective.ngOnInit();
return ionIcon;
}
ngOnDestroy() {
this.mutationObserver.disconnect();
this.destroy();
}
}