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 { Directive, ElementRef, Input, OnDestroy, OnInit } from '@angular/core';
import { CoreCancellablePromise } from '@classes/cancellable-promise'; import { CoreCancellablePromise } from '@classes/cancellable-promise';
import { CoreLoadingComponent } from '@components/loading/loading'; import { CoreLoadingComponent } from '@components/loading/loading';
import { CoreSettingsHelper } from '@features/settings/services/settings-helper';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreColors } from '@singletons/colors';
import { CoreComponentsRegistry } from '@singletons/components-registry'; import { CoreComponentsRegistry } from '@singletons/components-registry';
import { CoreDom } from '@singletons/dom'; import { CoreDom } from '@singletons/dom';
import { CoreEventObserver } from '@singletons/events'; import { CoreEventObserver } from '@singletons/events';
import { Subscription } from 'rxjs';
import { CoreFormatTextDirective } from './format-text'; import { CoreFormatTextDirective } from './format-text';
const defaultMaxHeight = 80; const defaultMaxHeight = 80;
@ -50,6 +53,7 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
protected maxHeight = defaultMaxHeight; protected maxHeight = defaultMaxHeight;
protected expandedHeight = 0; protected expandedHeight = 0;
protected resizeListener?: CoreEventObserver; protected resizeListener?: CoreEventObserver;
protected darkModeListener?: Subscription;
protected domPromise?: CoreCancellablePromise<void>; protected domPromise?: CoreCancellablePromise<void>;
protected uniqueId: string; protected uniqueId: string;
@ -92,6 +96,10 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
this.resizeListener = CoreDom.onWindowResize(() => { this.resizeListener = CoreDom.onWindowResize(() => {
this.calculateHeight(); this.calculateHeight();
}, 50); }, 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'); this.element.classList.remove('collapsible-loading-height');
// If cannot calculate height, shorten always. // 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 { ngOnDestroy(): void {
this.resizeListener?.off(); this.resizeListener?.off();
this.darkModeListener?.unsubscribe();
this.domPromise?.cancel(); this.domPromise?.cancel();
} }

View File

@ -90,30 +90,44 @@ export class CoreColors {
* Returns the hex code from any color css type (ie named). * Returns the hex code from any color css type (ie named).
* *
* @param color Color in any format. * @param color Color in any format.
* @returns Color in hex format. * @return Color in hex format.
*/ */
static getColorHex(color: string): string { static getColorHex(color: string): string {
const d = document.createElement('div'); const rgba = CoreColors.getColorRGBA(color, true);
d.style.color = color; if (rgba.length === 0) {
document.body.appendChild(d);
// Color in RGB .
const matches = getComputedStyle(d).color.match(/\d+/g) || [];
if (matches.length == 0) {
return ''; return '';
} }
const rgba = matches.map((a) => parseInt(a, 10));
const hex = [0,1,2].map( const hex = [0,1,2].map(
(idx) => this.componentToHex(rgba[idx]), (idx) => this.componentToHex(rgba[idx]),
).join(''); ).join('');
document.body.removeChild(d);
return '#' + hex; 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. * Gets the luma of a color.
* *