MOBILE-3833 style: Dynamic collapsible item background

main
Pau Ferrer Ocaña 2022-03-29 15:28:31 +02:00
parent 0051bb29d5
commit b129d3777b
2 changed files with 63 additions and 13 deletions

View File

@ -15,11 +15,14 @@
import { Directive, ElementRef, Input, OnDestroy, OnInit } from '@angular/core';
import { CoreCancellablePromise } from '@classes/cancellable-promise';
import { CoreLoadingComponent } from '@components/loading/loading';
import { CoreSettingsHelper } from '@features/settings/services/settings-helper';
import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons';
import { CoreColors } from '@singletons/colors';
import { CoreComponentsRegistry } from '@singletons/components-registry';
import { CoreDom } from '@singletons/dom';
import { CoreEventObserver } from '@singletons/events';
import { Subscription } from 'rxjs';
import { CoreFormatTextDirective } from './format-text';
const defaultMaxHeight = 80;
@ -50,6 +53,7 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
protected maxHeight = defaultMaxHeight;
protected expandedHeight = 0;
protected resizeListener?: CoreEventObserver;
protected darkModeListener?: Subscription;
protected domPromise?: CoreCancellablePromise<void>;
protected uniqueId: string;
@ -92,6 +96,10 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
this.resizeListener = CoreDom.onWindowResize(() => {
this.calculateHeight();
}, 50);
this.darkModeListener = CoreSettingsHelper.onDarkModeChange().subscribe(() => {
this.setGradientColor();
});
}
/**
@ -135,7 +143,34 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
this.element.classList.remove('collapsible-loading-height');
// If cannot calculate height, shorten always.
this.setExpandButtonEnabled(!this.expandedHeight || this.expandedHeight >= this.maxHeight);
const enable = !this.expandedHeight || this.expandedHeight >= this.maxHeight;
this.setExpandButtonEnabled(enable);
this.setGradientColor();
}
/**
* Sets the gradient color based on the background.
*/
protected setGradientColor(): void {
if (!this.toggleExpandEnabled) {
return;
}
let coloredElement: HTMLElement | null = this.element;
let backgroundColor = [0, 0, 0, 0];
let background = '';
while (coloredElement && backgroundColor[3] === 0) {
background = getComputedStyle(coloredElement).backgroundColor;
backgroundColor = CoreColors.getColorRGBA(background);
coloredElement = coloredElement.parentElement;
}
if (backgroundColor[3] !== 0) {
delete(backgroundColor[3]);
const bgList = backgroundColor.join(',');
this.element.style.setProperty('--background-gradient-rgb', `${bgList}`);
}
}
/**
@ -241,6 +276,7 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
*/
ngOnDestroy(): void {
this.resizeListener?.off();
this.darkModeListener?.unsubscribe();
this.domPromise?.cancel();
}

View File

@ -90,30 +90,44 @@ export class CoreColors {
* Returns the hex code from any color css type (ie named).
*
* @param color Color in any format.
* @returns Color in hex format.
* @return Color in hex format.
*/
static getColorHex(color: string): string {
const d = document.createElement('div');
d.style.color = color;
document.body.appendChild(d);
// Color in RGB .
const matches = getComputedStyle(d).color.match(/\d+/g) || [];
if (matches.length == 0) {
const rgba = CoreColors.getColorRGBA(color, true);
if (rgba.length === 0) {
return '';
}
const rgba = matches.map((a) => parseInt(a, 10));
const hex = [0,1,2].map(
(idx) => this.componentToHex(rgba[idx]),
).join('');
document.body.removeChild(d);
return '#' + hex;
}
/**
* Returns RGBA color from any color format.
*
* @param color Color in any format.
* @param createElement Wether create a new element is needed to calculate value.
* @return Red, green, blue and alpha.
*/
static getColorRGBA(color: string, createElement = false): number[] {
if (createElement) {
const d = document.createElement('span');
d.style.color = color;
document.body.appendChild(d);
// Color in RGB.
color = getComputedStyle(d).color;
document.body.removeChild(d);
}
const matches = color.match(/\d+/g) || [];
return matches.map((a, index) => index < 3 ? parseInt(a, 10) : parseFloat(a));
}
/**
* Gets the luma of a color.
*