MOBILE-3565 core: Add empty box and icon properties
parent
5ed902882d
commit
176407a613
|
@ -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 {}
|
||||
|
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -32,8 +32,6 @@ export class CoreFaIconDirective implements OnChanges {
|
|||
|
||||
@Input() name = '';
|
||||
|
||||
// TODO: Support slash, RTL and fixed width.
|
||||
|
||||
protected element: HTMLElement;
|
||||
|
||||
protected logger: CoreLogger;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue