improve speeddial

This commit is contained in:
rubikscraft
2022-04-19 12:40:17 +02:00
parent 1e72489fc6
commit fce3ea3036
13 changed files with 185 additions and 118 deletions

View File

@@ -2,13 +2,22 @@ import { CommonModule } from '@angular/common';
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { FabComponent } from './normal/fab.component';
import { SpeedDialOptionDirective } from './speed-dial/speed-dial-option.directive';
import { SpeedDialComponent } from './speed-dial/speed-dial.component';
@NgModule({
declarations: [FabComponent, SpeedDialComponent],
imports: [CommonModule, MatIconModule, MatButtonModule],
declarations: [FabComponent, SpeedDialComponent, SpeedDialOptionDirective],
imports: [CommonModule, MatIconModule, MatButtonModule, MatTooltipModule],
schemas: [NO_ERRORS_SCHEMA],
exports: [FabComponent, SpeedDialComponent],
exports: [
FabComponent,
MatIconModule,
MatButtonModule,
MatTooltipModule,
SpeedDialComponent,
SpeedDialOptionDirective,
],
})
export class FabModule {}

View File

@@ -1,8 +1,8 @@
<div class="fabholder">
<div class="fab-wrapper">
<button
mat-fab
[color]="color"
class="fabposition fullanimate mat-elevation-z6"
class="fab-position fullanimate mat-elevation-z6"
(click)="onClick()"
aria-label=""
>

View File

@@ -0,0 +1,11 @@
import { Directive, Host, Optional } from '@angular/core';
import { MatTooltip } from '@angular/material/tooltip';
@Directive({
selector: 'speed-dial (button[mat-mini-fab], button[mat-fab])',
})
export class SpeedDialOptionDirective {
constructor(@Host() @Optional() test?: MatTooltip) {
if (test) test.position = 'left';
}
}

View File

@@ -9,13 +9,13 @@ import {
export const SpeedDialAnimation = trigger('speedDialAnimation', [
transition(':enter', [
query('button', [
query('[mat-mini-fab]', [
style({ transform: 'scale(0)' }),
stagger(-50, [animate(100, style({ transform: 'scale(1)' }))]),
]),
]),
transition(':leave', [
query('button', [
query('[mat-mini-fab]', [
style({ transform: 'scale(1)' }),
stagger(50, [animate(150, style({ transform: 'scale(0)' }))]),
]),

View File

@@ -1,32 +1,31 @@
<div class="fabholder">
<div class="fab-wrapper">
<div
class="fabposition"
class="fab-position"
(mouseenter)="enter()"
(mouseleave)="leave()"
[class.speeddial-is-open]="isOpen"
[class.speed-dial-is-open]="isOpen"
>
<div class="speeddial-options" [@speedDialAnimation] (@speedDialAnimation.done)="done()" *ngIf="isOpen">
<button mat-mini-fab color="primary">
<mat-icon>menu</mat-icon>
</button>
<button mat-mini-fab color="primary">
<mat-icon>edit</mat-icon>
</button>
<button class="pog" mat-mini-fab color="primary">
<mat-icon>filter_list</mat-icon>
</button>
<div
class="speed-dial-options"
[@speedDialAnimation]
(@speedDialAnimation.start)="animStart()"
(@speedDialAnimation.done)="animDone()"
*ngIf="isOpen"
>
<ng-content select="[mat-mini-fab]"></ng-content>
</div>
<button
mat-fab
[color]="color"
class="fullanimate mat-elevation-z6"
class="speed-dial-main-button fullanimate mat-elevation-z6"
[matTooltip]="tooltip"
[matTooltipDisabled]="!isOpen"
(click)="click()"
aria-label=""
>
<mat-icon
[class.icon-rotate]="iconHover === undefined"
[class.icon-main]="iconHover !== undefined"
class="icon-main"
fontSet="material-icons-outlined"
[aria-label]="ariaLabel"
>

View File

@@ -1,45 +0,0 @@
.mat-button-wrapper {
position: relative;
}
mat-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.icon-main {
opacity: 1;
}
.icon-hover {
opacity: 0;
}
.speeddial-is-open {
.icon-main {
opacity: 0;
}
.icon-hover {
opacity: 1;
}
.icon-rotate {
transform: translate(-50%, -50%) rotate(45deg);
}
}
.speeddial-options {
display: flex;
width: 100%;
flex-direction: column;
align-content: center;
align-items: center;
& > * {
margin-bottom: 1rem;
}
padding-bottom: 1rem;
}

View File

@@ -1,44 +1,77 @@
import { Component, Input } from '@angular/core';
import { Component, Input, Output } from '@angular/core';
import { Subject } from 'rxjs';
import { SpeedDialAnimation } from './speed-dial.animation';
@Component({
selector: 'speed-dial',
templateUrl: './speed-dial.component.html',
styleUrls: ['./speed-dial.component.scss'],
animations: [SpeedDialAnimation],
})
export class SpeedDialComponent {
@Input('aria-label') ariaLabel: string = 'Floating Action Button';
@Input('icon') icon: string = 'add';
@Input('icon-hover') iconHover: string | undefined;
@Input('icon-hover') iconHover: string = 'close';
@Input('color') color: string = 'accent';
@Input('open-on-hover') openOnHover: boolean = true;
@Input('open-on-hover') openOnHover: boolean = false;
@Input('tooltip') tooltip: string;
@Output('main-click') clickEmitter = new Subject<void>();
public isOpen = false;
private isAnimating = true;
private wantsOpen = false;
private _isAnimating = false;
private _wantsOpen = false;
constructor() {}
private set isAnimating(val: boolean) {
this._isAnimating = val;
if (val === false && this._wantsOpen !== this.isOpen) {
this.isOpen = this._wantsOpen;
}
}
private set wantsOpen(val: boolean) {
this._wantsOpen = val;
if (!this._isAnimating) {
this.isOpen = val;
}
}
click() {
this.isOpen = !this.isOpen;
if (this._isAnimating) return;
this.wantsOpen = !this._wantsOpen;
if (this._wantsOpen === false) {
this.clickEmitter.next();
}
}
enter() {
if (this.openOnHover) {
this.isOpen = true;
this.wantsOpen = true;
}
}
leave() {
if (this.openOnHover) {
this.isOpen = false;
this.wantsOpen = false;
}
}
done() {
console.log('done');
animStart() {
this.isAnimating = true;
}
animDone() {
this.isAnimating = false;
}
open() {
this.wantsOpen = true;
}
close() {
this.wantsOpen = false;
}
}

View File

@@ -24,12 +24,7 @@
<copy-field label="Rst" [value]="imageLinks.rst"></copy-field>
</div>
<div class="col-12">
<button
mat-raised-button
class="m-1"
color="accent"
(click)="downloadImage()"
>
<button mat-raised-button class="m-1" color="accent" (click)="download()">
Download
</button>
@@ -45,4 +40,26 @@
</div>
</div>
<speed-dial></speed-dial>
<speed-dial
icon="menu"
icon-hover="download"
tooltip="Download the image"
[open-on-hover]="true"
(main-click)="download()"
#speedDial
>
<button
mat-mini-fab
matTooltip="Close menu"
color="primary"
(click)="speedDial.close()"
>
<mat-icon>close</mat-icon>
</button>
<button mat-mini-fab matTooltip="Info about the action" color="primary">
<mat-icon>edit</mat-icon>
</button>
<button mat-mini-fab matTooltip="Info about the action" color="primary">
<mat-icon>filter_list</mat-icon>
</button>
</speed-dial>

View File

@@ -35,7 +35,7 @@ export class ViewComponent implements OnInit {
this.imageLinks = this.imageService.CreateImageLinksFromID(id);
}
downloadImage() {
download() {
this.utilService.downloadFile(this.imageLinks.source);
}

View File

@@ -0,0 +1,72 @@
@use "../node_modules/bootstrap/scss/bootstrap-grid.scss" as bs;
// Fabs
.fab-wrapper {
display: flex;
justify-content: flex-end;
.fab-position {
position: fixed;
bottom: 2rem;
z-index: 8;
@include bs.media-breakpoint-down(xxl) {
right: 4rem;
}
@include bs.media-breakpoint-down(xl) {
right: 2rem;
}
@include bs.media-breakpoint-up(xl) {
bottom: 4rem;
}
@include bs.media-breakpoint-up(xxl) {
transform: translateX(3rem);
}
}
.speed-dial-options {
display: flex;
width: 100%;
flex-direction: column;
align-content: center;
align-items: center;
padding-bottom: 1rem;
[mat-mini-fab] {
margin-bottom: 1rem;
}
}
.speed-dial-main-button {
mat-icon {
position: absolute;
top: 50%;
left: 50%;
}
}
.icon-main {
opacity: 1;
transform: translate(-50%, -50%);
}
.icon-hover {
opacity: 0;
transform: translate(-50%, -50%) rotate(-45deg);
}
.speed-dial-is-open {
.icon-main {
opacity: 0;
transform: translate(-50%, -50%) rotate(45deg);
}
.icon-hover {
opacity: 1;
transform: translate(-50%, -50%);
}
}
}

View File

@@ -3,6 +3,7 @@
@use "./material/material-theme.scss";
@use "./fixes.scss";
@use "./personal.scss";
@use "./fab.scss";
@use "./snackbar.scss";

View File

@@ -1,5 +1,3 @@
@use "../node_modules/bootstrap/scss/bootstrap-grid.scss" as bs;
// Create white border around content
.content-border {
border-radius: 20px;
@@ -48,34 +46,6 @@
}
}
// Fabs
.fabholder {
display: flex;
justify-content: flex-end;
& .fabposition {
position: fixed;
bottom: 2rem;
z-index: 8;
@include bs.media-breakpoint-down(xxl) {
right: 4rem;
}
@include bs.media-breakpoint-down(xl) {
right: 2rem;
}
@include bs.media-breakpoint-up(xl) {
bottom: 4rem;
}
@include bs.media-breakpoint-up(xxl) {
transform: translateX(3rem);
}
}
}
// Anim
.container,