From ed0f1670f8fb749faf822d6ebb12252a2eefa28d Mon Sep 17 00:00:00 2001 From: eugene-sinitsyn Date: Wed, 4 Mar 2020 19:31:08 +0300 Subject: [PATCH] Implement ripple effect for material themes --- package-lock.json | 8 +++++++ package.json | 1 + src/app/@core/core.module.ts | 3 +++ src/app/@core/utils/ripple.service.ts | 11 ++++++++++ .../components/header/header.component.ts | 9 ++++++-- src/app/@theme/styles/_ripple.scss | 21 +++++++++++++++++++ src/app/@theme/styles/styles.scss | 2 ++ src/app/@theme/theme.module.ts | 5 +++-- .../pages/dashboard/dashboard.component.ts | 4 ++++ .../status-card/status-card.component.scss | 1 - .../status-card/status-card.component.ts | 2 +- .../temperature/temperature.component.html | 8 +++---- 12 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 src/app/@core/utils/ripple.service.ts create mode 100644 src/app/@theme/styles/_ripple.scss diff --git a/package-lock.json b/package-lock.json index 3dff34a2..569b8f8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -990,6 +990,14 @@ "integrity": "sha512-Id3hmPR5UeWAKsDeB6+O7m+4+FpUr5zcYdM8xXAzTjjn8laSuDUMb17wsAVRntPgRJv4SeaqUbWevwSkM5KExA==", "dev": true }, + "@angular/material": { + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-10.1.3.tgz", + "integrity": "sha512-6ygbCVcejFydmZUlOcNreiWQTvL4kOrEp/M51DV70hqffTnxajCzaRe2MQhxisENB/bR8mtMvf8YY3Rsys/HCw==", + "requires": { + "tslib": "^2.0.0" + } + }, "@angular/platform-browser": { "version": "10.0.10", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-10.0.10.tgz", diff --git a/package.json b/package.json index e2b2b29f..8bff4775 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@angular/core": "^10.0.10", "@angular/forms": "^10.0.10", "@angular/google-maps": "^10.1.3", + "@angular/material": "^10.1.3", "@angular/platform-browser": "^10.0.10", "@angular/platform-browser-dynamic": "^10.0.10", "@angular/router": "^10.0.10", diff --git a/src/app/@core/core.module.ts b/src/app/@core/core.module.ts index 1135104a..26bf0743 100644 --- a/src/app/@core/core.module.ts +++ b/src/app/@core/core.module.ts @@ -1,5 +1,6 @@ import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { MAT_RIPPLE_GLOBAL_OPTIONS } from '@angular/material/core'; import { NbAuthModule, NbDummyAuthStrategy } from '@nebular/auth'; import { NbSecurityModule, NbRoleProvider } from '@nebular/security'; import { of as observableOf } from 'rxjs'; @@ -51,6 +52,7 @@ import { CountryOrderService } from './mock/country-order.service'; import { StatsProgressBarService } from './mock/stats-progress-bar.service'; import { VisitorsAnalyticsService } from './mock/visitors-analytics.service'; import { SecurityCamerasService } from './mock/security-cameras.service'; +import { RippleService } from './utils/ripple.service'; import { MockDataModule } from './mock/mock-data.module'; const socialLinks = [ @@ -91,6 +93,7 @@ const DATA_SERVICES = [ { provide: StatsProgressBarData, useClass: StatsProgressBarService }, { provide: VisitorsAnalyticsData, useClass: VisitorsAnalyticsService }, { provide: SecurityCamerasData, useClass: SecurityCamerasService }, + {provide: MAT_RIPPLE_GLOBAL_OPTIONS, useExisting: RippleService}, ]; export class NbSimpleRoleProvider extends NbRoleProvider { diff --git a/src/app/@core/utils/ripple.service.ts b/src/app/@core/utils/ripple.service.ts new file mode 100644 index 00000000..5efb7a3c --- /dev/null +++ b/src/app/@core/utils/ripple.service.ts @@ -0,0 +1,11 @@ +import { Injectable } from '@angular/core'; +import { RippleGlobalOptions } from '@angular/material/core'; + +@Injectable({providedIn: 'root'}) +export class RippleService implements RippleGlobalOptions { + public disabled: boolean = false; + + public toggle(enabled: boolean): void { + this.disabled = !enabled; + } +} diff --git a/src/app/@theme/components/header/header.component.ts b/src/app/@theme/components/header/header.component.ts index 6376e343..a556db90 100644 --- a/src/app/@theme/components/header/header.component.ts +++ b/src/app/@theme/components/header/header.component.ts @@ -5,6 +5,7 @@ import { UserData } from '../../../@core/data/users'; import { LayoutService } from '../../../@core/utils'; import { map, takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; +import { RippleService } from '../../../@core/utils/ripple.service'; @Component({ selector: 'ngx-header', @@ -53,7 +54,8 @@ export class HeaderComponent implements OnInit, OnDestroy { private themeService: NbThemeService, private userService: UserData, private layoutService: LayoutService, - private breakpointService: NbMediaBreakpointsService) { + private breakpointService: NbMediaBreakpointsService, + private rippleService: RippleService) { } ngOnInit() { @@ -76,7 +78,10 @@ export class HeaderComponent implements OnInit, OnDestroy { map(({ name }) => name), takeUntil(this.destroy$), ) - .subscribe(themeName => this.currentTheme = themeName); + .subscribe(themeName => { + this.currentTheme = themeName; + this.rippleService.toggle(themeName?.startsWith('material')); + }); } ngOnDestroy() { diff --git a/src/app/@theme/styles/_ripple.scss b/src/app/@theme/styles/_ripple.scss new file mode 100644 index 00000000..f77ad29b --- /dev/null +++ b/src/app/@theme/styles/_ripple.scss @@ -0,0 +1,21 @@ +@mixin ngx-ripple() { + .mat-ripple { + overflow: hidden; + position: relative; + + &:not(:empty) { + transform: translateZ(0); + } + } + + .mat-ripple-element { + position: absolute; + border-radius: 50%; + pointer-events: none; + transition: opacity, transform 0ms cubic-bezier(0, 0, 0.2, 1); + transform: scale(0); + // switch ripple color depending on selected theme + background-color: nb-theme(background-alternative-color-4); + opacity: .1; + } +} \ No newline at end of file diff --git a/src/app/@theme/styles/styles.scss b/src/app/@theme/styles/styles.scss index 3f5a8927..15c2de14 100644 --- a/src/app/@theme/styles/styles.scss +++ b/src/app/@theme/styles/styles.scss @@ -18,6 +18,7 @@ @import './layout'; @import './overrides'; +@import './ripple'; // install the framework and custom global styles @include nb-install() { @@ -31,4 +32,5 @@ @include ngx-pace-theme(); @include nb-overrides(); + @include ngx-ripple(); }; diff --git a/src/app/@theme/theme.module.ts b/src/app/@theme/theme.module.ts index 06fa6b0f..dc5593c9 100644 --- a/src/app/@theme/theme.module.ts +++ b/src/app/@theme/theme.module.ts @@ -1,5 +1,6 @@ import { ModuleWithProviders, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { MatRippleModule } from '@angular/material/core'; import { NbActionsModule, NbLayoutModule, @@ -73,8 +74,8 @@ const PIPES = [ ]; @NgModule({ - imports: [CommonModule, ...NB_MODULES], - exports: [CommonModule, ...PIPES, ...COMPONENTS], + imports: [CommonModule, MatRippleModule, ...NB_MODULES], + exports: [CommonModule, MatRippleModule, ...PIPES, ...COMPONENTS], declarations: [...COMPONENTS, ...PIPES], }) export class ThemeModule { diff --git a/src/app/pages/dashboard/dashboard.component.ts b/src/app/pages/dashboard/dashboard.component.ts index c359216a..083d3bdd 100644 --- a/src/app/pages/dashboard/dashboard.component.ts +++ b/src/app/pages/dashboard/dashboard.component.ts @@ -54,6 +54,8 @@ export class DashboardComponent implements OnDestroy { cosmic: CardSettings[]; corporate: CardSettings[]; dark: CardSettings[]; + 'material-dark': CardSettings[]; + 'material-light': CardSettings[]; } = { default: this.commonStatusCardsSet, cosmic: this.commonStatusCardsSet, @@ -76,6 +78,8 @@ export class DashboardComponent implements OnDestroy { }, ], dark: this.commonStatusCardsSet, + 'material-dark': this.commonStatusCardsSet, + 'material-light': this.commonStatusCardsSet, }; constructor(private themeService: NbThemeService, diff --git a/src/app/pages/dashboard/status-card/status-card.component.scss b/src/app/pages/dashboard/status-card/status-card.component.scss index 03be02f5..261f13cf 100644 --- a/src/app/pages/dashboard/status-card/status-card.component.scss +++ b/src/app/pages/dashboard/status-card/status-card.component.scss @@ -5,7 +5,6 @@ flex-direction: row; align-items: center; height: 6rem; - overflow: visible; .icon-container { height: 100%; diff --git a/src/app/pages/dashboard/status-card/status-card.component.ts b/src/app/pages/dashboard/status-card/status-card.component.ts index 16276408..3ffd6ad2 100644 --- a/src/app/pages/dashboard/status-card/status-card.component.ts +++ b/src/app/pages/dashboard/status-card/status-card.component.ts @@ -4,7 +4,7 @@ import { Component, Input } from '@angular/core'; selector: 'ngx-status-card', styleUrls: ['./status-card.component.scss'], template: ` - +
diff --git a/src/app/pages/dashboard/temperature/temperature.component.html b/src/app/pages/dashboard/temperature/temperature.component.html index 8f6c0e4b..9f6c4345 100644 --- a/src/app/pages/dashboard/temperature/temperature.component.html +++ b/src/app/pages/dashboard/temperature/temperature.component.html @@ -20,16 +20,16 @@
- + - + - + - +