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>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
<ucap-ui-float-action-button
|
||||
[fabButtons]="fabButtons"
|
||||
(buttonClick)="onClickFab($event)"
|
||||
></ucap-ui-float-action-button>
|
||||
</div>
|
||||
|
|
|
@ -31,6 +31,9 @@ export class LeftSideComponent implements OnInit {
|
|||
/** 조직도에서 부서원 선택 */
|
||||
selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] = [];
|
||||
|
||||
/** FAB */
|
||||
fabButtons: { icon: string }[];
|
||||
|
||||
constructor(
|
||||
private store: Store<any>,
|
||||
private dialogService: DialogService,
|
||||
|
@ -41,6 +44,20 @@ export class LeftSideComponent implements OnInit {
|
|||
this.badgeChatUnReadCount$ = this.store.pipe(
|
||||
select(AppStore.MessengerSelector.SyncSelector.selectChatUnreadCount)
|
||||
);
|
||||
this.fabButtons = [
|
||||
{
|
||||
icon: 'timeline'
|
||||
},
|
||||
{
|
||||
icon: 'view_headline'
|
||||
},
|
||||
{
|
||||
icon: 'room'
|
||||
},
|
||||
{
|
||||
icon: 'lock'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
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,
|
||||
animation,
|
||||
useAnimation,
|
||||
stagger
|
||||
stagger,
|
||||
keyframes
|
||||
} from '@angular/animations';
|
||||
|
||||
const customAnimation = animation(
|
||||
|
@ -548,5 +549,52 @@ export const ucapAnimations = [
|
|||
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 { FileUploadQueueComponent } from './components/file-upload-queue.component';
|
||||
import { UI_COMMON_COMPONENTS } from './components/index';
|
||||
|
||||
import { BottomSheetService } from './services/bottom-sheet.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 { DateToStringForChatRoomListPipe } from './pipes/dates.pipe';
|
||||
|
||||
const COMPONENTS = [FileUploadQueueComponent];
|
||||
const COMPONENTS = [...UI_COMMON_COMPONENTS];
|
||||
const DIALOGS = [AlertDialogComponent, ConfirmDialogComponent];
|
||||
const DIRECTIVES = [
|
||||
ClickOutsideDirective,
|
||||
|
|
Loading…
Reference in New Issue
Block a user