This commit is contained in:
crusader
2018-08-18 10:04:59 +09:00
parent df60d66951
commit 0be9c89d35
16 changed files with 303 additions and 214 deletions

View File

@@ -4,6 +4,7 @@ import {
import {
DropdownPanelComponent,
PopupPanelComponent
} from './primeng';
import {
@@ -18,6 +19,7 @@ import {
export const COMPONENTS = [
DropdownPanelComponent,
MenuBarComponent,
PopupPanelComponent,
ToolbarComponent,
TitleBarComponent,
WindowControlsComponent,

View File

@@ -1,18 +1,12 @@
<div [class]="styleClass" [ngStyle]="style" [ngClass]="{'ui-dropdownpanel ui-widget': true}">
<div [ngClass]="{'ui-widget ui-dropdownpanel-header ui-state-default':true, 'ui-state-active':visible}" (click)="toggle($event)">
<ng-content select="p-header"></ng-content>
</div>
<div [ngClass]="'ui-popuppanel-header'" *ngIf="headerFacet" [ngStyle]="headerStyle" [class]="headerStyleClass" (click)="popupPanel.toggle($event)">
<ng-content select="p-header"></ng-content>
</div>
<div #container [ngClass]="{'ui-dropdownpanel-container ui-menu ui-widget ui-widget-content': true, 'ui-menu-dynamic ui-shadow': popup}"
[class]="dropdownStyleClass" [ngStyle]="dropdownStyle" (click)="preventDocumentDefault=true" *ngIf="!popup || visible" [@overlayAnimation]="'visible'"
[@.disabled]="popup !== true" (@overlayAnimation.start)="onOverlayAnimationStart($event)">
<div class="ui-dropdownpanel-content-wrapper" [ngClass]="{'ui-dropdownpanel-content-wrapper-overflown': !visible||animating}">
<div class="ui-dropdownpanel-content ui-widget-content">
<ng-content></ng-content>
</div>
<div class="ui-dropdownpanel-footer" *ngIf="footerFacet">
<ng-content select="p-footer"></ng-content>
</div>
<of-p-popupPanel #popupPanel [style]="style" [styleClass]="styleClass" [appendTo]="blockTarget">
<div [ngClass]="'ui-popuppanel-content'">
<ng-content></ng-content>
</div>
</div>
<div [ngClass]="'ui-popuppanel-footer'" *ngIf="footerFacet" [ngStyle]="footerStyle" [class]="footerStyleClass">
<ng-content select="p-footer"></ng-content>
</div>
</of-p-popupPanel>

View File

@@ -1,24 +1,25 @@
.ui-dropdownpanel {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
flex-shrink: 0;
&-header {
.ui-popuppanel-header {
width: 100%;
height: 100%;
align-items: center;
padding: var(--spacing);
overflow: hidden;
background-color: var(--toolbar-button-background-color)
}
.ui-dropdownpanel-container {
background-color: rgba(201, 76, 76, 0.3);
}
.ui-dropdownpanel-footer {
padding-top: 1em;
}
}
.ui-popuppanel-body {
padding: 1em;
}
.ui-popuppanel-title {
font-size: 1.5em;
font-weight: bold;
margin-bottom: .5em;
}
.ui-popuppanel-subtitle {
opacity: .7;
margin-bottom: .5em;
margin-top: -.25em;
font-weight: bold;
}
.ui-popuppanel-footer {
padding-top: 1em;
}

View File

@@ -1,185 +1,30 @@
import { Component, ElementRef, OnDestroy, Input, Renderer2, ViewChild, ContentChild } from '@angular/core';
import { trigger, state, style, transition, animate, AnimationEvent } from '@angular/animations';
import { Header, Footer, DomHandler } from 'primeng/primeng';
import { Component, Input, ContentChild } from '@angular/core';
import { Header, Footer } from 'primeng/primeng';
@Component({
selector: 'p-dropdownPanel',
selector: 'of-p-dropdownPanel',
templateUrl: './dropdown-panel.component.html',
styleUrls: ['./dropdown-panel.component.scss'],
animations: [
trigger('overlayAnimation', [
state('void', style({
// transform: 'translateY(5%)',
transform: 'translate3d(0, 0, 0)',
opacity: 0
})),
state('visible', style({
// transform: 'translateY(0)',
transform: 'translate3d(0, 0, 0)',
opacity: 1
})),
transition('void => visible', animate('225ms ease-in-out')),
transition('visible => void', animate('195ms ease-in-out'))
// transition('void => visible', animate('225ms ease-out')),
// transition('visible => void', animate('195ms ease-in'))
// transition('visible => void', animate('400ms cubic-bezier(0.86, 0, 0.07, 1)')),
// transition('void => visible', animate('400ms cubic-bezier(0.86, 0, 0.07, 1)'))
])
],
providers: [DomHandler]
})
export class DropdownPanelComponent implements OnDestroy {
@Input() popup = true;
export class DropdownPanelComponent {
@Input() blockTarget: any;
@Input() style: any;
@Input() styleClass: string;
@Input() dropdownStyle: any;
@Input() headerStyle: any;
@Input() dropdownStyleClass: string;
@Input() headerStyleClass: string;
@Input() appendTo: any;
@Input() footerStyle: any;
@Input() autoZIndex = true;
@Input() baseZIndex = 0;
@ViewChild('container') containerViewChild: ElementRef;
@Input() footerStyleClass: string;
@ContentChild(Header) headerFacet;
@ContentChild(Footer) footerFacet;
container: HTMLDivElement;
documentClickListener: any;
documentResizeListener: any;
preventDocumentDefault: boolean;
target: any;
visible = false;
constructor(
public el: ElementRef,
public domHandler: DomHandler,
public renderer: Renderer2
) {
}
toggle(event) {
if (this.visible) {
this.hide();
} else {
this.show(event);
}
this.preventDocumentDefault = true;
}
show(event) {
this.target = event.currentTarget;
this.visible = true;
this.preventDocumentDefault = true;
}
onOverlayAnimationStart(event: AnimationEvent) {
switch (event.toState) {
case 'visible':
if (this.popup) {
this.container = event.element;
this.moveOnTop();
this.appendOverlay();
this.domHandler.absolutePosition(this.container, this.target);
this.bindDocumentClickListener();
this.bindDocumentResizeListener();
}
break;
case 'void':
this.onOverlayHide();
break;
}
}
appendOverlay() {
if (this.appendTo) {
if (this.appendTo === 'body') {
document.body.appendChild(this.container);
} else {
this.domHandler.appendChild(this.container, this.appendTo);
}
}
}
restoreOverlayAppend() {
if (this.container && this.appendTo) {
this.el.nativeElement.appendChild(this.container);
}
}
moveOnTop() {
if (this.autoZIndex) {
this.container.style.zIndex = String(this.baseZIndex + (++DomHandler.zindex));
}
}
hide() {
this.visible = false;
}
onWindowResize() {
this.hide();
}
bindDocumentClickListener() {
if (!this.documentClickListener) {
this.documentClickListener = this.renderer.listen('document', 'click', () => {
if (!this.preventDocumentDefault) {
this.hide();
}
this.preventDocumentDefault = false;
});
}
}
unbindDocumentClickListener() {
if (this.documentClickListener) {
this.documentClickListener();
this.documentClickListener = null;
}
}
bindDocumentResizeListener() {
this.documentResizeListener = this.onWindowResize.bind(this);
window.addEventListener('resize', this.documentResizeListener);
}
unbindDocumentResizeListener() {
if (this.documentResizeListener) {
window.removeEventListener('resize', this.documentResizeListener);
this.documentResizeListener = null;
}
}
onOverlayHide() {
this.unbindDocumentClickListener();
this.unbindDocumentResizeListener();
this.preventDocumentDefault = false;
this.target = null;
}
ngOnDestroy() {
if (this.popup) {
this.restoreOverlayAppend();
this.onOverlayHide();
}
}
constructor() { }
}

View File

@@ -1 +1,2 @@
export { DropdownPanelComponent } from './dropdown-panel.component';
export { PopupPanelComponent } from './popup-panel.component';

View File

@@ -0,0 +1,8 @@
<div #container [ngClass]="{'ui-popuppanel ui-widget ui-widget-content ui-corner-all': true, 'ui-popuppanel-dynamic ui-shadow': popup}"
[class]="styleClass" [ngStyle]="style" (click)="preventDocumentDefault=true" *ngIf="!popup || visible" [@overlayAnimation]="'visible'"
[@.disabled]="popup !== true" (@overlayAnimation.start)="onOverlayAnimationStart($event)" (@overlayAnimation.done)="onOverlayAnimationDone($event)">
<ng-content></ng-content>
</div>
<p-blockUI id="block-ui" [target]="blockTarget" [blocked]="visible">
</p-blockUI>

View File

@@ -0,0 +1,12 @@
.ui-popuppanel {
width: 12.5em;
padding: .25em;
}
.ui-popuppanel.ui-popuppanel-dynamic {
position: absolute;
}
#block-ui {
min-height:100vh;
}

View File

@@ -0,0 +1,173 @@
import { NgModule, Component, ElementRef, OnDestroy, Input, Renderer2, ViewChild, Inject, forwardRef } from '@angular/core';
import { trigger, state, style, transition, animate, AnimationEvent } from '@angular/animations';
import { DomHandler } from 'primeng/primeng';
@Component({
selector: 'of-p-popupPanel',
templateUrl: './popup-panel.component.html',
styleUrls: ['./popup-panel.component.scss'],
animations: [
trigger('overlayAnimation', [
state('void', style({
transform: 'translateY(5%)',
opacity: 0
})),
state('visible', style({
transform: 'translateY(0)',
opacity: 1
})),
transition('void => visible', animate('225ms ease-out')),
transition('visible => void', animate('195ms ease-in'))
])
],
providers: [DomHandler]
})
export class PopupPanelComponent implements OnDestroy {
@Input() blockTarget: any;
@Input() style: any;
@Input() styleClass: string;
@Input() appendTo: any;
@Input() autoZIndex = true;
@Input() baseZIndex = 0;
@ViewChild('container') containerViewChild: ElementRef;
private readonly popup = true;
container: HTMLDivElement;
documentClickListener: any;
documentResizeListener: any;
preventDocumentDefault: boolean;
target: any;
visible: boolean;
blockUIVisible = false;
constructor(public el: ElementRef, public domHandler: DomHandler, public renderer: Renderer2) { }
toggle(event) {
if (this.visible) {
this.hide();
} else {
this.show(event);
}
this.preventDocumentDefault = true;
}
show(event) {
this.target = event.currentTarget;
this.visible = true;
this.preventDocumentDefault = true;
}
onOverlayAnimationStart(event: AnimationEvent) {
switch (event.toState) {
case 'visible':
if (this.popup) {
this.container = event.element;
this.moveOnTop();
this.appendOverlay();
this.domHandler.absolutePosition(this.container, this.target);
this.bindDocumentClickListener();
this.bindDocumentResizeListener();
}
break;
case 'void':
this.onOverlayHide();
break;
}
}
onOverlayAnimationDone(event: AnimationEvent) {
console.log('onOverlayAnimationDone');
}
appendOverlay() {
if (this.appendTo) {
if (this.appendTo === 'body') {
document.body.appendChild(this.container);
} else {
this.domHandler.appendChild(this.container, this.appendTo);
}
}
}
restoreOverlayAppend() {
if (this.container && this.appendTo) {
this.el.nativeElement.appendChild(this.container);
}
}
moveOnTop() {
if (this.autoZIndex) {
this.container.style.zIndex = String(this.baseZIndex + (++DomHandler.zindex));
}
}
hide() {
this.visible = false;
}
onWindowResize() {
this.hide();
}
bindDocumentClickListener() {
if (!this.documentClickListener) {
this.documentClickListener = this.renderer.listen('document', 'click', () => {
if (!this.preventDocumentDefault) {
this.hide();
}
this.preventDocumentDefault = false;
});
}
}
unbindDocumentClickListener() {
if (this.documentClickListener) {
this.documentClickListener();
this.documentClickListener = null;
}
}
bindDocumentResizeListener() {
this.documentResizeListener = this.onWindowResize.bind(this);
window.addEventListener('resize', this.documentResizeListener);
}
unbindDocumentResizeListener() {
if (this.documentResizeListener) {
window.removeEventListener('resize', this.documentResizeListener);
this.documentResizeListener = null;
}
}
onOverlayHide() {
this.unbindDocumentClickListener();
this.unbindDocumentResizeListener();
this.preventDocumentDefault = false;
this.target = null;
}
ngOnDestroy() {
if (this.popup) {
this.restoreOverlayAppend();
this.onOverlayHide();
}
}
}