MOBILE-3833 style: Dynamic collapsible item background
parent
0051bb29d5
commit
b129d3777b
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue