MOBILE-3565 core: Add empty box and icon properties

main
Pau Ferrer Ocaña 2020-10-28 17:24:51 +01:00
parent 5ed902882d
commit 176407a613
10 changed files with 170 additions and 41 deletions

View File

@ -20,6 +20,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { CoreIconComponent } from './icon/icon';
import { CoreLoadingComponent } from './loading/loading';
import { CoreShowPasswordComponent } from './show-password/show-password';
import { CoreEmptyBoxComponent } from './empty-box/empty-box';
import { CoreDirectivesModule } from '@app/directives/directives.module';
import { CorePipesModule } from '@app/pipes/pipes.module';
@ -28,6 +29,7 @@ import { CorePipesModule } from '@app/pipes/pipes.module';
CoreIconComponent,
CoreLoadingComponent,
CoreShowPasswordComponent,
CoreEmptyBoxComponent,
],
imports: [
CommonModule,
@ -40,6 +42,7 @@ import { CorePipesModule } from '@app/pipes/pipes.module';
CoreIconComponent,
CoreLoadingComponent,
CoreShowPasswordComponent,
CoreEmptyBoxComponent,
],
})
export class CoreComponentsModule {}

View File

@ -0,0 +1,9 @@
<div class="core-empty-box ion-padding" [class.core-empty-box-inline]="(!image && !icon) || inline">
<div class="core-empty-box-content">
<img *ngIf="image && !icon" [src]="image" role="presentation">
<ion-icon *ngIf="icon" [name]="icon" [class.icon-flip-rtl]="flipIconRtl">
</ion-icon>
<p *ngIf="message" [class.ion-padding-top]="image || icon">{{ message }}</p>
<ng-content></ng-content>
</div>
</div>

View File

@ -0,0 +1,70 @@
:host {
.core-empty-box {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: table;
height: 100%;
width: 100%;
margin: 0;
clear: both;
pointer-events: none;
.core-empty-box-content {
margin: 0;
display: table-cell;
text-align: center;
vertical-align: middle;
pointer-events: auto;
}
&.core-empty-box-inline {
position: relative;
z-index: initial;
top: initial;
right: initial;
bottom: 0;
left: initial;
height: auto;
}
ion-icon {
font-size: 120px;
}
img {
height: 125px;
width: 145px;
margin: 0 auto;
}
p {
font-size: 120%;
}
}
&.core-empty-box-clickable .core-empty-box {
z-index: 0;
}
@media (max-width: 350px) {
.core-empty-box {
position: relative;
height: auto;
margin-top: 50px;
ion-icon {
font-size: 100px;
}
img {
height: 104px;
width: 121px;
}
}
}
}
:host-context(core-block-course-blocks) .core-empty-box {
position: relative;
}

View File

@ -0,0 +1,43 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, Input } from '@angular/core';
/**
* Component to show an empty box message. It will show an optional icon or image and a text centered on page.
*
* Use class="core-empty-box-clickable" if you want to add some clickable elements to the box.
*
* Usage:
* <core-empty-box *ngIf="empty" icon="bell" [message]="'core.emptymessage' | translate"></core-empty-box>
*/
@Component({
selector: 'core-empty-box',
templateUrl: 'core-empty-box.html',
styleUrls: ['empty-box.scss'],
})
export class CoreEmptyBoxComponent {
@Input() message = ''; // Message to display.
@Input() icon?: string; // Name of the icon to use.
@Input() image?: string; // Image source. If an icon is provided, image won't be used.
/**
* If this has to be shown inline instead of occupying whole page.
* If image or icon is not supplied, it's true by default.
*/
@Input() inline?: boolean;
@Input() flipIconRtl?: boolean; // Whether to flip the icon in RTL. Defaults to false.
}

View File

@ -123,31 +123,3 @@
}
}
}
// TODO ionic 5
:host-context([dir=rtl]) ion-icon {
&.core-icon-dir-flip,
&.fa-caret-right,
&.ion-md-send, &.ion-ios-send {
-webkit-transform: scale(-1, 1);
transform: scale(-1, 1);
}
}
:host {
&.icon-slash {
&::after {
content: " ";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: var(--ion-color-danger);
-webkit-mask: url("/assets/fonts/font-awesome/solid/slash.svg") no-repeat 50% 50%;
mask: url("/assets/fonts/font-awesome/solid/slash.svg") no-repeat 50% 50%;
-webkit-transform: scale(-1, 1);
transform: scale(-1, 1);
}
}
}

View File

@ -20,6 +20,7 @@ import { Component, Input, OnChanges, ElementRef, SimpleChange } from '@angular/
* the component will detect it.
*
* Check available icons at https://fontawesome.com/icons?d=gallery&m=free
*
* @deprecated since 3.9.3. Please use <ion-icon name="fa-icon"> instead.
*/
@Component({
@ -81,9 +82,9 @@ export class CoreIconComponent implements OnChanges {
}
if (this.isTrueProperty(this.flipRtl)) {
iconElement.classList.add('core-icon-dir-flip');
iconElement.classList.add('icon-flip-rtl');
} else {
iconElement.classList.remove('core-icon-dir-flip');
iconElement.classList.remove('icon-flip-rtl');
}
if (this.isTrueProperty(this.fixedWidth)) {
@ -96,10 +97,10 @@ export class CoreIconComponent implements OnChanges {
/**
* Check if the value is true or on.
*
* @param val value to be checked.
* @param val Value to be checked.
* @return If has a value equivalent to true.
*/
isTrueProperty(val: any): boolean {
isTrueProperty(val: unknown): boolean {
if (typeof val === 'string') {
val = val.toLowerCase().trim();

View File

@ -16,5 +16,7 @@
</ion-header>
<ion-content>
<!-- @todo -->
Home page.
</ion-content>
<core-empty-box icon="fa-home" [message]="'core.courses.nocourses' | translate">
<div>Home page</div>
</core-empty-box>
</ion-content>

View File

@ -1,4 +1,3 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
@ -11,18 +10,18 @@
</ion-header>
<ion-content>
<ion-item text-wrap>
<ion-item class="ion-text-wrap">
<ion-label><h2>{{ appName }} {{ versionName }}</h2></ion-label>
</ion-item>
<ion-item text-wrap (click)="openPage('licenses')" detail>
<ion-item button class="ion-text-wrap" (click)="openPage('licenses')" detail>
<ion-icon name="far-copyright" slot="start"></ion-icon>
<ion-label>{{ 'core.settings.opensourcelicenses' | translate }}</ion-label>
</ion-item>
<ion-item text-wrap *ngIf="privacyPolicy" [href]="privacyPolicy" core-link auto-login="no" detail>
<ion-item button class="ion-text-wrap" *ngIf="privacyPolicy" [href]="privacyPolicy" core-link auto-login="no" detail>
<ion-icon name="fa-user-shield" slot="start"></ion-icon>
<ion-label>{{ 'core.settings.privacypolicy' | translate }}</ion-label>
</ion-item>
<ion-item text-wrap (click)="openPage('deviceinfo')" detail>
<ion-item button class="ion-text-wrap" (click)="openPage('deviceinfo')" detail>
<ion-icon name="fa-mobile" slot="start"></ion-icon>
<ion-label>{{ 'core.settings.deviceinfo' | translate }}</ion-label>
</ion-item>

View File

@ -32,8 +32,6 @@ export class CoreFaIconDirective implements OnChanges {
@Input() name = '';
// TODO: Support slash, RTL and fixed width.
protected element: HTMLElement;
protected logger: CoreLogger;

View File

@ -4,3 +4,35 @@ ion-toolbar ion-back-button,
ion-toolbar .in-toolbar.button-clear {
--color: var(--ion-color-primary-contrast);
}
// Ion icon styles.
ion-icon {
&.icon-slash::after,
&.icon-backslash::after {
content: " ";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: var(--ion-color-danger);
-webkit-mask: url("/assets/fonts/font-awesome/solid/slash.svg") no-repeat 50% 50%;
mask: url("/assets/fonts/font-awesome/solid/slash.svg") no-repeat 50% 50%;
}
&.icon-slash::after {
-webkit-transform: scale(-1, 1);
transform: scale(-1, 1);
}
&.fa-fw {
text-align: center;
width: 1.25em;
}
}
[dir=rtl] ion-icon.icon-flip-rtl {
-webkit-transform: scale(-1, 1);
transform: scale(-1, 1);
}