From b129d3777bea1173aab93cb59ad64b1907bf5226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 29 Mar 2022 15:28:31 +0200 Subject: [PATCH] MOBILE-3833 style: Dynamic collapsible item background --- src/core/directives/collapsible-item.ts | 38 ++++++++++++++++++++++++- src/core/singletons/colors.ts | 38 +++++++++++++++++-------- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/src/core/directives/collapsible-item.ts b/src/core/directives/collapsible-item.ts index 5084f128a..3bac8a97c 100644 --- a/src/core/directives/collapsible-item.ts +++ b/src/core/directives/collapsible-item.ts @@ -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; 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(); } diff --git a/src/core/singletons/colors.ts b/src/core/singletons/colors.ts index d0e0e3dfa..ed70b8bdf 100644 --- a/src/core/singletons/colors.ts +++ b/src/core/singletons/colors.ts @@ -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. *