FAB common component add
This commit is contained in:
parent
33e6566eff
commit
36a983a6fd
|
@ -44,4 +44,8 @@
|
||||||
<app-layout-chat-left-sidenav-call></app-layout-chat-left-sidenav-call>
|
<app-layout-chat-left-sidenav-call></app-layout-chat-left-sidenav-call>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
</mat-tab-group>
|
</mat-tab-group>
|
||||||
|
<ucap-ui-float-action-button
|
||||||
|
[fabButtons]="fabButtons"
|
||||||
|
(buttonClick)="onClickFab($event)"
|
||||||
|
></ucap-ui-float-action-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -31,6 +31,9 @@ export class LeftSideComponent implements OnInit {
|
||||||
/** 조직도에서 부서원 선택 */
|
/** 조직도에서 부서원 선택 */
|
||||||
selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] = [];
|
selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] = [];
|
||||||
|
|
||||||
|
/** FAB */
|
||||||
|
fabButtons: { icon: string }[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private store: Store<any>,
|
private store: Store<any>,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
|
@ -41,6 +44,20 @@ export class LeftSideComponent implements OnInit {
|
||||||
this.badgeChatUnReadCount$ = this.store.pipe(
|
this.badgeChatUnReadCount$ = this.store.pipe(
|
||||||
select(AppStore.MessengerSelector.SyncSelector.selectChatUnreadCount)
|
select(AppStore.MessengerSelector.SyncSelector.selectChatUnreadCount)
|
||||||
);
|
);
|
||||||
|
this.fabButtons = [
|
||||||
|
{
|
||||||
|
icon: 'timeline'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'view_headline'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'room'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'lock'
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
async onClickNewChat() {
|
async onClickNewChat() {
|
||||||
|
@ -106,4 +123,9 @@ export class LeftSideComponent implements OnInit {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** FAB */
|
||||||
|
onClickFab(params: { btn: { icon: string } }) {
|
||||||
|
this.logger.debug('FAB click', params.btn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@ import {
|
||||||
state,
|
state,
|
||||||
animation,
|
animation,
|
||||||
useAnimation,
|
useAnimation,
|
||||||
stagger
|
stagger,
|
||||||
|
keyframes
|
||||||
} from '@angular/animations';
|
} from '@angular/animations';
|
||||||
|
|
||||||
const customAnimation = animation(
|
const customAnimation = animation(
|
||||||
|
@ -548,5 +549,52 @@ export const ucapAnimations = [
|
||||||
query('content > :leave', animateChild(), { optional: true })
|
query('content > :leave', animateChild(), { optional: true })
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
]),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Floating ACtion Button Animation.
|
||||||
|
*/
|
||||||
|
trigger('fabToggler', [
|
||||||
|
state(
|
||||||
|
'inactive',
|
||||||
|
style({
|
||||||
|
transform: 'rotate(0deg)'
|
||||||
|
})
|
||||||
|
),
|
||||||
|
state(
|
||||||
|
'active',
|
||||||
|
style({
|
||||||
|
transform: 'rotate(225deg)'
|
||||||
|
})
|
||||||
|
),
|
||||||
|
transition('* <=> *', animate('200ms cubic-bezier(0.4, 0.0, 0.2, 1)'))
|
||||||
|
]),
|
||||||
|
trigger('speedDialStagger', [
|
||||||
|
transition('* => *', [
|
||||||
|
query(':enter', style({ opacity: 0 }), { optional: true }),
|
||||||
|
|
||||||
|
query(
|
||||||
|
':enter',
|
||||||
|
stagger('40ms', [
|
||||||
|
animate(
|
||||||
|
'200ms cubic-bezier(0.4, 0.0, 0.2, 1)',
|
||||||
|
keyframes([
|
||||||
|
style({ opacity: 0, transform: 'translateY(10px)' }),
|
||||||
|
style({ opacity: 1, transform: 'translateY(0)' })
|
||||||
|
])
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
{ optional: true }
|
||||||
|
),
|
||||||
|
|
||||||
|
query(
|
||||||
|
':leave',
|
||||||
|
animate(
|
||||||
|
'200ms cubic-bezier(0.4, 0.0, 0.2, 1)',
|
||||||
|
keyframes([style({ opacity: 1 }), style({ opacity: 0 })])
|
||||||
|
),
|
||||||
|
{ optional: true }
|
||||||
|
)
|
||||||
|
])
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<div
|
||||||
|
id="fab-dismiss"
|
||||||
|
*ngIf="fabTogglerState === 'active'"
|
||||||
|
(click)="onToggleFab()"
|
||||||
|
></div>
|
||||||
|
<div class="fab-container">
|
||||||
|
<button mat-fab class="fab-toggler" (click)="onToggleFab()">
|
||||||
|
<mat-icon [@fabToggler]="fabTogglerState">add</mat-icon>
|
||||||
|
</button>
|
||||||
|
<div [@speedDialStagger]="buttons.length">
|
||||||
|
<button
|
||||||
|
*ngFor="let btn of buttons"
|
||||||
|
mat-mini-fab
|
||||||
|
class="fab-secondary"
|
||||||
|
color="secondary"
|
||||||
|
(click)="onClickButton(btn)"
|
||||||
|
>
|
||||||
|
<mat-icon>{{ btn.icon }}</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,34 @@
|
||||||
|
.fab-container {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 15px;
|
||||||
|
right: 15px;
|
||||||
|
z-index: 100;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-bottom: 17px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fab-toggler {
|
||||||
|
float: right;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fab-dismiss {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* tslint:disable:no-unused-variable */
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
|
import { FloatActionButtonComponent } from './float-action-button.component';
|
||||||
|
|
||||||
|
describe('FloatActionButtonComponent', () => {
|
||||||
|
let component: FloatActionButtonComponent;
|
||||||
|
let fixture: ComponentFixture<FloatActionButtonComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [FloatActionButtonComponent]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(FloatActionButtonComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
import { ucapAnimations } from '@ucap-webmessenger/ui';
|
||||||
|
|
||||||
|
export interface FloatActionButton {
|
||||||
|
/** Meterial Icon type */
|
||||||
|
icon: string;
|
||||||
|
divisionType?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ucap-ui-float-action-button',
|
||||||
|
templateUrl: './float-action-button.component.html',
|
||||||
|
styleUrls: ['./float-action-button.component.scss'],
|
||||||
|
animations: ucapAnimations
|
||||||
|
})
|
||||||
|
export class FloatActionButtonComponent implements OnInit {
|
||||||
|
@Input()
|
||||||
|
fabButtons: FloatActionButton[] = [];
|
||||||
|
buttons = [];
|
||||||
|
fabTogglerState = 'inactive';
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
buttonClick = new EventEmitter<{
|
||||||
|
btn: FloatActionButton;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
|
showItems() {
|
||||||
|
this.fabTogglerState = 'active';
|
||||||
|
this.buttons = this.fabButtons;
|
||||||
|
}
|
||||||
|
|
||||||
|
hideItems() {
|
||||||
|
this.fabTogglerState = 'inactive';
|
||||||
|
this.buttons = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
onToggleFab() {
|
||||||
|
this.buttons.length ? this.hideItems() : this.showItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickButton(btn: FloatActionButton) {
|
||||||
|
this.hideItems();
|
||||||
|
this.buttonClick.emit({ btn });
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { FileUploadQueueComponent } from './file-upload-queue.component';
|
||||||
|
import { FloatActionButtonComponent } from './float-action-button.component';
|
||||||
|
|
||||||
|
export const UI_COMMON_COMPONENTS = [
|
||||||
|
FileUploadQueueComponent,
|
||||||
|
FloatActionButtonComponent
|
||||||
|
];
|
|
@ -12,7 +12,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
|
|
||||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||||
|
|
||||||
import { FileUploadQueueComponent } from './components/file-upload-queue.component';
|
import { UI_COMMON_COMPONENTS } from './components/index';
|
||||||
|
|
||||||
import { BottomSheetService } from './services/bottom-sheet.service';
|
import { BottomSheetService } from './services/bottom-sheet.service';
|
||||||
import { ClipboardService } from './services/clipboard.service';
|
import { ClipboardService } from './services/clipboard.service';
|
||||||
|
@ -30,7 +30,7 @@ import { BytesPipe } from './pipes/bytes.pipe';
|
||||||
import { LinefeedToHtmlPipe, HtmlToLinefeedPipe } from './pipes/linefeed.pipe';
|
import { LinefeedToHtmlPipe, HtmlToLinefeedPipe } from './pipes/linefeed.pipe';
|
||||||
import { DateToStringForChatRoomListPipe } from './pipes/dates.pipe';
|
import { DateToStringForChatRoomListPipe } from './pipes/dates.pipe';
|
||||||
|
|
||||||
const COMPONENTS = [FileUploadQueueComponent];
|
const COMPONENTS = [...UI_COMMON_COMPONENTS];
|
||||||
const DIALOGS = [AlertDialogComponent, ConfirmDialogComponent];
|
const DIALOGS = [AlertDialogComponent, ConfirmDialogComponent];
|
||||||
const DIRECTIVES = [
|
const DIRECTIVES = [
|
||||||
ClickOutsideDirective,
|
ClickOutsideDirective,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user