Improve thumbnail loading animation

- Minimize content shift by leaving space around the animation (same as the placeholder)
- Replace animation with more compact spinner to prevent wrapping when the thumbnail is very narrow
This commit is contained in:
Yury Bondarenko
2022-09-21 10:24:18 +02:00
parent 13d33d802f
commit 891c9165d7
7 changed files with 33 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
<div>
<div *ngIf="!spinner">
<label *ngIf="showMessage && message">{{ message }}</label>
<div class="loader">
<span class="l-1"></span>
@@ -13,3 +13,6 @@
<span class="l-10"></span>
</div>
</div>
<div *ngIf='spinner' class="spinner spinner-border" role="status">
<span class="sr-only">{{ message }}</span>
</div>

View File

@@ -71,3 +71,7 @@ span.l-10 {-webkit-animation-delay: 0s;animation-delay: 0s;-ms-animation-delay:
50% {-ms-transform: translateX(30px); opacity: 0;}
100% {opacity: 0;}
}
.spinner {
color: var(--bs-gray-600);
}

View File

@@ -15,6 +15,11 @@ export class LoadingComponent implements OnDestroy, OnInit {
@Input() message: string;
@Input() showMessage = true;
/**
* Show a more compact spinner animation instead of the default one
*/
@Input() spinner = false;
private subscription: Subscription;
constructor(private translate: TranslateService) {

View File

@@ -15,8 +15,9 @@ export class ThemedLoadingComponent extends ThemedComponent<LoadingComponent> {
@Input() message: string;
@Input() showMessage = true;
@Input() spinner = false;
protected inAndOutputNames: (keyof LoadingComponent & keyof this)[] = ['message', 'showMessage'];
protected inAndOutputNames: (keyof LoadingComponent & keyof this)[] = ['message', 'showMessage', 'spinner'];
constructor(
protected resolver: ComponentFactoryResolver,

View File

@@ -1,14 +1,20 @@
<div class="thumbnail" [class.limit-width]="limitWidth" *ngVar="(isLoading$ | async) as isLoading">
<ds-themed-loading *ngIf="isLoading" class="thumbnail-content" [showMessage]="false">
text-content
</ds-themed-loading>
<div *ngIf="isLoading" class="thumbnail-content outer">
<div class="inner">
<div class="centered">
<ds-themed-loading [spinner]="true"></ds-themed-loading>
</div>
</div>
</div>
<ng-container *ngVar="(src$ | async) as src">
<!-- don't use *ngIf="!isLoading" so the thumbnail can load in while the animation is playing -->
<img *ngIf="src !== null" class="thumbnail-content img-fluid" [ngClass]="{'d-none': isLoading}"
[src]="src | dsSafeUrl" [alt]="alt | translate" (error)="errorHandler()" (load)="successHandler()">
<div *ngIf="src === null && !isLoading" class="thumbnail-content outer">
<div class="inner">
<div class="thumbnail-placeholder w-100 h-100 p-3 lead">{{ placeholder | translate }}</div>
<div class="thumbnail-placeholder centered p-3 lead">
{{ placeholder | translate }}
</div>
</div>
</div>
</ng-container>

View File

@@ -26,6 +26,10 @@ img {
border: var(--ds-thumbnail-placeholder-border);
color: var(--ds-thumbnail-placeholder-color);
font-weight: bold;
}
> .centered {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;

View File

@@ -244,7 +244,7 @@ describe('ThumbnailComponent', () => {
fixture.detectChanges();
const placeholder = fixture.debugElement.query(By.css('div.thumbnail-placeholder')).nativeElement;
expect(placeholder.innerHTML).toBe('TRANSLATED ' + comp.placeholder);
expect(placeholder.innerHTML).toContain('TRANSLATED ' + comp.placeholder);
});
});
});