Browse Source

fix(theme-shared): fix modal styles and animations

pull/1838/head
TheDiaval 7 years ago
parent
commit
093e62eb64
  1. 63
      npm/ng-packs/packages/theme-shared/src/lib/animations/fade.animations.ts
  2. 14
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.animations.ts
  3. 44
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html
  4. 20
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts
  5. 18
      npm/ng-packs/packages/theme-shared/src/lib/contants/styles.ts

63
npm/ng-packs/packages/theme-shared/src/lib/animations/fade.animations.ts

@ -1,79 +1,74 @@
import { animate, animation, style } from '@angular/animations'; import { animate, animation, style } from '@angular/animations';
export const fadeIn = animation( export const fadeIn = animation([style({ opacity: '0' }), animate('{{ time}} {{ easing }}', style({ opacity: '1' }))], {
[style({ opacity: '0', display: '{{ display }}' }), animate('{{ time}} {{ easing }}', style({ opacity: '1' }))], params: { time: '350ms', easing: 'ease' },
{ params: { time: '350ms', easing: 'ease', display: 'block' } } });
);
export const fadeOut = animation( export const fadeOut = animation(
[ [style({ opacity: '1' }), animate('{{ time}} {{ easing }}', style({ opacity: '0' }))],
style({ opacity: '1' }), { params: { time: '350ms', easing: 'ease' } },
animate('{{ time}} {{ easing }}', style({ opacity: '0' })),
style({ opacity: '0', display: 'none' })
],
{ params: { time: '350ms', easing: 'ease' } }
); );
export const fadeInDown = animation( export const fadeInDown = animation(
[ [
style({ opacity: '0', display: '{{ display }}', transform: '{{ transform }} translateY(-20px)' }), style({ opacity: '0', transform: '{{ transform }} translateY(-20px)' }),
animate('{{ time }} {{ easing }}', style({ opacity: '1', transform: '{{ transform }} translateY(0)' })) animate('{{ time }} {{ easing }}', style({ opacity: '1', transform: '{{ transform }} translateY(0)' })),
], ],
{ params: { time: '350ms', easing: 'ease', display: 'block', transform: 'translate(-50%, -50%)' } } { params: { time: '350ms', easing: 'ease', transform: '' } },
); );
export const fadeInUp = animation( export const fadeInUp = animation(
[ [
style({ opacity: '0', display: '{{ display }}', transform: '{{ transform }} translateY(20px)' }), style({ opacity: '0', transform: '{{ transform }} translateY(20px)' }),
animate('{{ time }} {{ easing }}', style({ opacity: '1', transform: '{{ transform }} translateY(0)' })) animate('{{ time }} {{ easing }}', style({ opacity: '1', transform: '{{ transform }} translateY(0)' })),
], ],
{ params: { time: '350ms', easing: 'ease', display: 'block', transform: 'translate(-50%, -50%)' } } { params: { time: '350ms', easing: 'ease', transform: '' } },
); );
export const fadeInLeft = animation( export const fadeInLeft = animation(
[ [
style({ opacity: '0', display: '{{ display }}', transform: '{{ transform }} translateX(20px)' }), style({ opacity: '0', transform: '{{ transform }} translateX(20px)' }),
animate('{{ time }} {{ easing }}', style({ opacity: '1', transform: '{{ transform }} translateX(0)' })) animate('{{ time }} {{ easing }}', style({ opacity: '1', transform: '{{ transform }} translateX(0)' })),
], ],
{ params: { time: '350ms', easing: 'ease', display: 'block', transform: 'translate(-50%, -50%)' } } { params: { time: '350ms', easing: 'ease', transform: '' } },
); );
export const fadeInRight = animation( export const fadeInRight = animation(
[ [
style({ opacity: '0', display: '{{ display }}', transform: '{{ transform }} translateX(-20px)' }), style({ opacity: '0', transform: '{{ transform }} translateX(-20px)' }),
animate('{{ time }} {{ easing }}', style({ opacity: '1', transform: '{{ transform }} translateX(0)' })) animate('{{ time }} {{ easing }}', style({ opacity: '1', transform: '{{ transform }} translateX(0)' })),
], ],
{ params: { time: '350ms', easing: 'ease', display: 'block', transform: 'translate(-50%, -50%)' } } { params: { time: '350ms', easing: 'ease', transform: '' } },
); );
export const fadeOutDown = animation( export const fadeOutDown = animation(
[ [
style({ opacity: '1', display: '{{ display }}', transform: '{{ transform }} translateY(0)' }), style({ opacity: '1', transform: '{{ transform }} translateY(0)' }),
animate('{{ time }} {{ easing }}', style({ opacity: '0', transform: '{{ transform }} translateY(20px)' })) animate('{{ time }} {{ easing }}', style({ opacity: '0', transform: '{{ transform }} translateY(20px)' })),
], ],
{ params: { time: '350ms', easing: 'ease', display: 'block', transform: 'translate(-50%, -50%)' } } { params: { time: '350ms', easing: 'ease', transform: '' } },
); );
export const fadeOutUp = animation( export const fadeOutUp = animation(
[ [
style({ opacity: '1', display: '{{ display }}', transform: '{{ transform }} translateY(0)' }), style({ opacity: '1', transform: '{{ transform }} translateY(0)' }),
animate('{{ time }} {{ easing }}', style({ opacity: '0', transform: '{{ transform }} translateY(-20px)' })) animate('{{ time }} {{ easing }}', style({ opacity: '0', transform: '{{ transform }} translateY(-20px)' })),
], ],
{ params: { time: '350ms', easing: 'ease', display: 'block', transform: 'translate(-50%, -50%)' } } { params: { time: '350ms', easing: 'ease', transform: '' } },
); );
export const fadeOutLeft = animation( export const fadeOutLeft = animation(
[ [
style({ opacity: '1', display: '{{ display }}', transform: '{{ transform }} translateX(0)' }), style({ opacity: '1', transform: '{{ transform }} translateX(0)' }),
animate('{{ time }} {{ easing }}', style({ opacity: '0', transform: '{{ transform }} translateX(20px)' })) animate('{{ time }} {{ easing }}', style({ opacity: '0', transform: '{{ transform }} translateX(20px)' })),
], ],
{ params: { time: '350ms', easing: 'ease', display: 'block', transform: 'translate(-50%, -50%)' } } { params: { time: '350ms', easing: 'ease', transform: '' } },
); );
export const fadeOutRight = animation( export const fadeOutRight = animation(
[ [
style({ opacity: '1', display: '{{ display }}', transform: '{{ transform }} translateX(0)' }), style({ opacity: '1', transform: '{{ transform }} translateX(0)' }),
animate('{{ time }} {{ easing }}', style({ opacity: '0', transform: '{{ transform }} translateX(-20px)' })) animate('{{ time }} {{ easing }}', style({ opacity: '0', transform: '{{ transform }} translateX(-20px)' })),
], ],
{ params: { time: '350ms', easing: 'ease', display: 'block', transform: 'translate(-50%, -50%)' } } { params: { time: '350ms', easing: 'ease', transform: '' } },
); );

14
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.animations.ts

@ -1,14 +1,12 @@
import { trigger, state, style, transition, useAnimation } from '@angular/animations'; import { transition, trigger, useAnimation } from '@angular/animations';
import { fadeInDown, fadeOut, fadeIn } from '../../animations'; import { fadeIn, fadeInDown, fadeOut } from '../../animations/fade.animations';
export const backdropAnimation = trigger('backdrop', [ export const backdropAnimation = trigger('backdrop', [
state('void', style({ opacity: '0' })), transition(':enter', useAnimation(fadeIn)),
state('*', style({ opacity: '1' })), transition(':leave', useAnimation(fadeOut)),
transition('void => *', useAnimation(fadeIn)),
transition('* => void', useAnimation(fadeOut))
]); ]);
export const dialogAnimation = trigger('dialog', [ export const dialogAnimation = trigger('dialog', [
transition('void => *', useAnimation(fadeInDown)), transition(':enter', useAnimation(fadeInDown)),
transition('* => void', useAnimation(fadeOut)) transition(':leave', useAnimation(fadeOut)),
]); ]);

44
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html

@ -1,21 +1,29 @@
<div class="modal {{ modalClass }}" tabindex="-1" role="dialog" *ngIf="visible"> <ng-container *ngIf="visible">
<div class="modal-backdrop" [@backdrop]="visible" (click)="close()"></div> <div class="modal show {{ modalClass }}" tabindex="-1" role="dialog">
<div id="abp-modal-dialog" class="modal-dialog modal-{{ size }}" role="document" [@dialog]="visible" #abpModalContent> <div class="modal-backdrop" [@backdrop]="isModalOpen" (click)="close()"></div>
<div id="abp-modal-content" class="modal-content"> <div
<div id="abp-modal-header" class="modal-header"> id="abp-modal-dialog"
<ng-container *ngTemplateOutlet="abpHeader"></ng-container> class="modal-dialog modal-{{ size }}"
role="document"
<button id="abp-modal-close-button" type="button" class="close" aria-label="Close" (click)="close()"> [@dialog]="isModalOpen"
<span aria-hidden="true">&times;</span> #abpModalContent
</button> >
</div> <div id="abp-modal-content" class="modal-content">
<div id="abp-modal-body" class="modal-body"> <div id="abp-modal-header" class="modal-header">
<ng-container *ngTemplateOutlet="abpBody"></ng-container> <ng-container *ngTemplateOutlet="abpHeader"></ng-container>
</div> ​
<div id="abp-modal-footer" class="modal-footer"> <button id="abp-modal-close-button" type="button" class="close" aria-label="Close" (click)="close()">
<ng-container *ngTemplateOutlet="abpFooter"></ng-container> <span aria-hidden="true">&times;</span>
</button>
</div>
<div id="abp-modal-body" class="modal-body">
<ng-container *ngTemplateOutlet="abpBody"></ng-container>
</div>
<div id="abp-modal-footer" class="modal-footer">
<ng-container *ngTemplateOutlet="abpFooter"></ng-container>
</div>
</div> </div>
</div> </div>
<ng-content></ng-content>
</div> </div>
<ng-content></ng-content> </ng-container>
</div>

20
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts

@ -9,12 +9,12 @@ import {
Renderer2, Renderer2,
TemplateRef, TemplateRef,
ViewChild, ViewChild,
ViewChildren ViewChildren,
} from '@angular/core'; } from '@angular/core';
import { fromEvent, Subject } from 'rxjs'; import { fromEvent, Subject } from 'rxjs';
import { debounceTime, filter, takeUntil } from 'rxjs/operators'; import { debounceTime, filter, takeUntil } from 'rxjs/operators';
import { Toaster } from '../../models/toaster'; import { Toaster } from '../../models/toaster';
import { ConfirmationService } from '../../services'; import { ConfirmationService } from '../../services/confirmation.service';
import { ButtonComponent } from '../button/button.component'; import { ButtonComponent } from '../button/button.component';
import { backdropAnimation, dialogAnimation } from './modal.animations'; import { backdropAnimation, dialogAnimation } from './modal.animations';
@ -23,7 +23,7 @@ export type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
@Component({ @Component({
selector: 'abp-modal', selector: 'abp-modal',
templateUrl: './modal.component.html', templateUrl: './modal.component.html',
animations: [backdropAnimation, dialogAnimation] animations: [backdropAnimation, dialogAnimation],
}) })
export class ModalComponent implements OnDestroy { export class ModalComponent implements OnDestroy {
@Input() @Input()
@ -32,7 +32,11 @@ export class ModalComponent implements OnDestroy {
} }
set visible(value: boolean) { set visible(value: boolean) {
if (typeof value !== 'boolean') return; if (typeof value !== 'boolean') return;
this.isModalOpen = value;
this._visible = value; this._visible = value;
this.visibleChange.emit(value);
if (value) { if (value) {
this.listen(); this.listen();
this.renderer.addClass(document.body, 'modal-open'); this.renderer.addClass(document.body, 'modal-open');
@ -89,6 +93,8 @@ export class ModalComponent implements OnDestroy {
_busy = false; _busy = false;
isModalOpen = false;
isConfirmationOpen = false; isConfirmationOpen = false;
destroy$ = new Subject<void>(); destroy$ = new Subject<void>();
@ -103,7 +109,7 @@ export class ModalComponent implements OnDestroy {
if (this.busy) return; if (this.busy) return;
const nodes = getFlatNodes( const nodes = getFlatNodes(
(this.modalContent.nativeElement.querySelector('#abp-modal-body') as HTMLElement).childNodes (this.modalContent.nativeElement.querySelector('#abp-modal-body') as HTMLElement).childNodes,
); );
if (hasNgDirty(nodes)) { if (hasNgDirty(nodes)) {
@ -128,7 +134,7 @@ export class ModalComponent implements OnDestroy {
.pipe( .pipe(
takeUntil(this.destroy$), takeUntil(this.destroy$),
debounceTime(150), debounceTime(150),
filter((key: KeyboardEvent) => key && key.code === 'Escape') filter((key: KeyboardEvent) => key && key.code === 'Escape'),
) )
.subscribe(_ => { .subscribe(_ => {
this.close(); this.close();
@ -139,7 +145,7 @@ export class ModalComponent implements OnDestroy {
fromEvent(this.abpClose.nativeElement, 'click') fromEvent(this.abpClose.nativeElement, 'click')
.pipe( .pipe(
takeUntil(this.destroy$), takeUntil(this.destroy$),
filter(() => !!this.modalContent) filter(() => !!this.modalContent),
) )
.subscribe(() => this.close()); .subscribe(() => this.close());
}, 0); }, 0);
@ -151,7 +157,7 @@ export class ModalComponent implements OnDestroy {
function getFlatNodes(nodes: NodeList): HTMLElement[] { function getFlatNodes(nodes: NodeList): HTMLElement[] {
return Array.from(nodes).reduce( return Array.from(nodes).reduce(
(acc, val) => [...acc, ...(val.childNodes && val.childNodes.length ? getFlatNodes(val.childNodes) : [val])], (acc, val) => [...acc, ...(val.childNodes && val.childNodes.length ? getFlatNodes(val.childNodes) : [val])],
[] [],
); );
} }

18
npm/ng-packs/packages/theme-shared/src/lib/contants/styles.ts

@ -28,8 +28,22 @@ export default `
min-width: 215px; min-width: 215px;
} }
.modal { .modal.show {
background-color: rgba(0, 0, 0, .6); display: block !important;
}
.modal-backdrop {
position: absolute !important;
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
background-color: rgba(0, 0, 0, .6) !important;
z-index: 1040 !important;
}
.modal-dialog {
z-index: 1050 !important;
} }
.abp-ellipsis-inline { .abp-ellipsis-inline {

Loading…
Cancel
Save