MOBILE-3833 loading: Improve loading spinner styles
parent
aa4f1cdee1
commit
cb63541195
|
@ -2,8 +2,4 @@
|
|||
<ion-spinner color="primary" aria-hidden="true"></ion-spinner>
|
||||
<p class="core-loading-message" *ngIf="message" role="status">{{message}}</p>
|
||||
</div>
|
||||
<div #content class="core-loading-content" [id]="uniqueId" [attr.aria-busy]="!hideUntil" @coreShowHideAnimation
|
||||
[class.opacity-hide]="!hideUntil">
|
||||
<ng-content *ngIf="loaded">
|
||||
</ng-content>
|
||||
</div>
|
||||
<ng-content *ngIf="loaded" @coreShowHideAnimation></ng-content>
|
||||
|
|
|
@ -1,5 +1,27 @@
|
|||
@import "~theme/globals";
|
||||
|
||||
@mixin inline() {
|
||||
min-height: var(--internal-loading-inline-min-height);
|
||||
max-height: 100vh; // In order show it on the page (content will be cut).
|
||||
|
||||
&:not(.core-loading-loaded) {
|
||||
position: relative;
|
||||
--contents-display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.core-loading-container {
|
||||
--loading-background: rgba(var(--loading-background-inline), 0.4);
|
||||
flex-direction: row;
|
||||
height: auto;
|
||||
width: auto;
|
||||
|
||||
.core-loading-message {
|
||||
@include margin(0, 0, 0, 10px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:host {
|
||||
--loading-background: var(--ion-background-color);
|
||||
--loading-background-inline: var(--ion-background-color-rgb);
|
||||
|
@ -8,27 +30,28 @@
|
|||
--loading-inline-margin: 0px;
|
||||
--loading-inline-min-height: 28px;
|
||||
--internal-loading-inline-min-height: var(--loading-inline-min-height);
|
||||
--content-display: contents;
|
||||
--loading-display: flex;
|
||||
--loading-display-message: block;
|
||||
--contents-display: contents;
|
||||
|
||||
position: static;
|
||||
color: var(--loading-text-color);
|
||||
@include core-transition(all, 200ms);
|
||||
|
||||
&.margin {
|
||||
--loading-inline-margin: 10px;
|
||||
--internal-loading-inline-min-height: calc(var(--loading-inline-min-height) + var(--loading-inline-margin) + var(--loading-inline-margin));
|
||||
}
|
||||
pointer-events: none;
|
||||
display: var(--contents-display);
|
||||
|
||||
&.core-loading-loaded {
|
||||
position: static;
|
||||
pointer-events: auto;
|
||||
--internal-loading-inline-min-height: 0px;
|
||||
}
|
||||
|
||||
ion-spinner {
|
||||
--color: var(--loading-spinner);
|
||||
color: var(--color);
|
||||
&.has-spacer {
|
||||
--contents-display: flex;
|
||||
min-height: 100%;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.core-loading-container {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
@include position(0, 0, 0, 0);
|
||||
height: 100%;
|
||||
|
@ -36,78 +59,38 @@
|
|||
z-index: 3;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--loading-text-color);
|
||||
background-color: var(--loading-background);
|
||||
@include core-transition(all, 200ms);
|
||||
display: flex;
|
||||
display: var(--loading-display);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.core-loading-content {
|
||||
@include core-transition(opacity, 200ms);
|
||||
display: var(--content-display);
|
||||
}
|
||||
|
||||
.core-loading-message {
|
||||
@include margin(10px, 0, 0, 0);
|
||||
}
|
||||
|
||||
&.core-loading-loaded {
|
||||
position: unset;
|
||||
display: contents;
|
||||
}
|
||||
|
||||
&.core-loading-inline {
|
||||
--loading-background: rgba(var(--loading-background-inline), 0.5);
|
||||
position: relative;
|
||||
display: block;
|
||||
min-height: var(--internal-loading-inline-min-height);
|
||||
|
||||
.core-loading-message {
|
||||
@include margin(0, 0, 0, 10px);
|
||||
@include margin(10px, 0, 0, 0);
|
||||
display: var(--loading-display-message);
|
||||
}
|
||||
|
||||
.core-loading-container {
|
||||
flex-direction: row;
|
||||
ion-spinner {
|
||||
--color: var(--loading-spinner);
|
||||
color: var(--color);
|
||||
}
|
||||
}
|
||||
|
||||
&.core-loading-full-height .core-loading-content {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.has-spacer {
|
||||
--content-display: flex;
|
||||
|
||||
.core-loading-content {
|
||||
min-height: 100%;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
&.list-item-limited-width .core-loading-content {
|
||||
max-width: var(--list-item-max-width);
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
}
|
||||
|
||||
&.safe-area-padding:not(.core-loading-inline) .core-loading-content,
|
||||
&.safe-area-padding-horizontal:not(.core-loading-inline) .core-loading-content {
|
||||
@include safe-area-padding-horizontal(0px, 0px);
|
||||
}
|
||||
|
||||
&.safe-area-padding:not(.core-loading-inline) .core-loading-content {
|
||||
padding-bottom: var(--ion-safe-area-bottom);
|
||||
> * {
|
||||
--ion-safe-area-bottom: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:host-context(ion-item) {
|
||||
&.core-loading-inline {
|
||||
position: static;
|
||||
display: block;
|
||||
@include inline();
|
||||
}
|
||||
}
|
||||
|
||||
// Force inline on some contexts.
|
||||
:host-context(ion-item),
|
||||
:host-context(core-block) {
|
||||
// Implicit Inline.
|
||||
@include inline();
|
||||
}
|
||||
|
||||
:host-context(.limited-width > ):not([slot]) {
|
||||
--contents-display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input, OnInit, OnChanges, SimpleChange, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
|
||||
import { Component, Input, OnInit, OnChanges, SimpleChange, ElementRef, AfterViewInit } from '@angular/core';
|
||||
|
||||
import { CoreEventLoadingChangedData, CoreEvents } from '@singletons/events';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
|
@ -50,15 +50,14 @@ import { AsyncComponent } from '@classes/async-component';
|
|||
})
|
||||
export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, AsyncComponent {
|
||||
|
||||
@Input() hideUntil: unknown; // Determine when should the contents be shown.
|
||||
@Input() hideUntil = false; // Determine when should the contents be shown.
|
||||
@Input() message?: string; // Message to show while loading.
|
||||
@Input() fullscreen = true; // Use the whole screen.
|
||||
|
||||
@ViewChild('content') content?: ElementRef;
|
||||
|
||||
uniqueId: string;
|
||||
protected element: HTMLElement; // Current element.
|
||||
loaded = false; // Only comes true once.
|
||||
|
||||
protected element: HTMLElement; // Current element.
|
||||
protected onReadyPromise = new CorePromisedValue<void>();
|
||||
|
||||
constructor(element: ElementRef) {
|
||||
|
@ -67,6 +66,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
|||
|
||||
// Calculate the unique ID.
|
||||
this.uniqueId = 'core-loading-content-' + CoreUtils.getUniqueId('CoreLoadingComponent');
|
||||
this.element.setAttribute('id', this.uniqueId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,7 +77,6 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
|||
// Default loading message.
|
||||
this.message = Translate.instant('core.loading');
|
||||
}
|
||||
|
||||
this.element.classList.toggle('core-loading-inline', !this.fullscreen);
|
||||
}
|
||||
|
||||
|
@ -85,7 +84,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
|||
* @inheritdoc
|
||||
*/
|
||||
ngAfterViewInit(): void {
|
||||
this.changeState(!!this.hideUntil);
|
||||
this.changeState(this.hideUntil);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,7 +92,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
|||
*/
|
||||
ngOnChanges(changes: { [name: string]: SimpleChange }): void {
|
||||
if (changes.hideUntil) {
|
||||
this.changeState(!!this.hideUntil);
|
||||
this.changeState(this.hideUntil);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +104,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
|||
*/
|
||||
async changeState(loaded: boolean): Promise<void> {
|
||||
this.element.classList.toggle('core-loading-loaded', loaded);
|
||||
this.content?.nativeElement.classList.toggle('core-loading-content', loaded);
|
||||
this.element.setAttribute('aria-busy', loaded ? 'false' : 'true');
|
||||
|
||||
if (!this.loaded && loaded) {
|
||||
this.loaded = true; // Only comes true once.
|
||||
|
|
Loading…
Reference in New Issue