Implement ripple effect for material themes

This commit is contained in:
eugene-sinitsyn 2020-03-04 19:31:08 +03:00 committed by Sergey Andrievskiy
parent 345c8836ca
commit ed0f1670f8
12 changed files with 65 additions and 10 deletions

8
package-lock.json generated
View file

@ -990,6 +990,14 @@
"integrity": "sha512-Id3hmPR5UeWAKsDeB6+O7m+4+FpUr5zcYdM8xXAzTjjn8laSuDUMb17wsAVRntPgRJv4SeaqUbWevwSkM5KExA==", "integrity": "sha512-Id3hmPR5UeWAKsDeB6+O7m+4+FpUr5zcYdM8xXAzTjjn8laSuDUMb17wsAVRntPgRJv4SeaqUbWevwSkM5KExA==",
"dev": true "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": { "@angular/platform-browser": {
"version": "10.0.10", "version": "10.0.10",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-10.0.10.tgz", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-10.0.10.tgz",

View file

@ -38,6 +38,7 @@
"@angular/core": "^10.0.10", "@angular/core": "^10.0.10",
"@angular/forms": "^10.0.10", "@angular/forms": "^10.0.10",
"@angular/google-maps": "^10.1.3", "@angular/google-maps": "^10.1.3",
"@angular/material": "^10.1.3",
"@angular/platform-browser": "^10.0.10", "@angular/platform-browser": "^10.0.10",
"@angular/platform-browser-dynamic": "^10.0.10", "@angular/platform-browser-dynamic": "^10.0.10",
"@angular/router": "^10.0.10", "@angular/router": "^10.0.10",

View file

@ -1,5 +1,6 @@
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MAT_RIPPLE_GLOBAL_OPTIONS } from '@angular/material/core';
import { NbAuthModule, NbDummyAuthStrategy } from '@nebular/auth'; import { NbAuthModule, NbDummyAuthStrategy } from '@nebular/auth';
import { NbSecurityModule, NbRoleProvider } from '@nebular/security'; import { NbSecurityModule, NbRoleProvider } from '@nebular/security';
import { of as observableOf } from 'rxjs'; 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 { StatsProgressBarService } from './mock/stats-progress-bar.service';
import { VisitorsAnalyticsService } from './mock/visitors-analytics.service'; import { VisitorsAnalyticsService } from './mock/visitors-analytics.service';
import { SecurityCamerasService } from './mock/security-cameras.service'; import { SecurityCamerasService } from './mock/security-cameras.service';
import { RippleService } from './utils/ripple.service';
import { MockDataModule } from './mock/mock-data.module'; import { MockDataModule } from './mock/mock-data.module';
const socialLinks = [ const socialLinks = [
@ -91,6 +93,7 @@ const DATA_SERVICES = [
{ provide: StatsProgressBarData, useClass: StatsProgressBarService }, { provide: StatsProgressBarData, useClass: StatsProgressBarService },
{ provide: VisitorsAnalyticsData, useClass: VisitorsAnalyticsService }, { provide: VisitorsAnalyticsData, useClass: VisitorsAnalyticsService },
{ provide: SecurityCamerasData, useClass: SecurityCamerasService }, { provide: SecurityCamerasData, useClass: SecurityCamerasService },
{provide: MAT_RIPPLE_GLOBAL_OPTIONS, useExisting: RippleService},
]; ];
export class NbSimpleRoleProvider extends NbRoleProvider { export class NbSimpleRoleProvider extends NbRoleProvider {

View file

@ -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;
}
}

View file

@ -5,6 +5,7 @@ import { UserData } from '../../../@core/data/users';
import { LayoutService } from '../../../@core/utils'; import { LayoutService } from '../../../@core/utils';
import { map, takeUntil } from 'rxjs/operators'; import { map, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { RippleService } from '../../../@core/utils/ripple.service';
@Component({ @Component({
selector: 'ngx-header', selector: 'ngx-header',
@ -53,7 +54,8 @@ export class HeaderComponent implements OnInit, OnDestroy {
private themeService: NbThemeService, private themeService: NbThemeService,
private userService: UserData, private userService: UserData,
private layoutService: LayoutService, private layoutService: LayoutService,
private breakpointService: NbMediaBreakpointsService) { private breakpointService: NbMediaBreakpointsService,
private rippleService: RippleService) {
} }
ngOnInit() { ngOnInit() {
@ -76,7 +78,10 @@ export class HeaderComponent implements OnInit, OnDestroy {
map(({ name }) => name), map(({ name }) => name),
takeUntil(this.destroy$), takeUntil(this.destroy$),
) )
.subscribe(themeName => this.currentTheme = themeName); .subscribe(themeName => {
this.currentTheme = themeName;
this.rippleService.toggle(themeName?.startsWith('material'));
});
} }
ngOnDestroy() { ngOnDestroy() {

View file

@ -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;
}
}

View file

@ -18,6 +18,7 @@
@import './layout'; @import './layout';
@import './overrides'; @import './overrides';
@import './ripple';
// install the framework and custom global styles // install the framework and custom global styles
@include nb-install() { @include nb-install() {
@ -31,4 +32,5 @@
@include ngx-pace-theme(); @include ngx-pace-theme();
@include nb-overrides(); @include nb-overrides();
@include ngx-ripple();
}; };

View file

@ -1,5 +1,6 @@
import { ModuleWithProviders, NgModule } from '@angular/core'; import { ModuleWithProviders, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MatRippleModule } from '@angular/material/core';
import { import {
NbActionsModule, NbActionsModule,
NbLayoutModule, NbLayoutModule,
@ -73,8 +74,8 @@ const PIPES = [
]; ];
@NgModule({ @NgModule({
imports: [CommonModule, ...NB_MODULES], imports: [CommonModule, MatRippleModule, ...NB_MODULES],
exports: [CommonModule, ...PIPES, ...COMPONENTS], exports: [CommonModule, MatRippleModule, ...PIPES, ...COMPONENTS],
declarations: [...COMPONENTS, ...PIPES], declarations: [...COMPONENTS, ...PIPES],
}) })
export class ThemeModule { export class ThemeModule {

View file

@ -54,6 +54,8 @@ export class DashboardComponent implements OnDestroy {
cosmic: CardSettings[]; cosmic: CardSettings[];
corporate: CardSettings[]; corporate: CardSettings[];
dark: CardSettings[]; dark: CardSettings[];
'material-dark': CardSettings[];
'material-light': CardSettings[];
} = { } = {
default: this.commonStatusCardsSet, default: this.commonStatusCardsSet,
cosmic: this.commonStatusCardsSet, cosmic: this.commonStatusCardsSet,
@ -76,6 +78,8 @@ export class DashboardComponent implements OnDestroy {
}, },
], ],
dark: this.commonStatusCardsSet, dark: this.commonStatusCardsSet,
'material-dark': this.commonStatusCardsSet,
'material-light': this.commonStatusCardsSet,
}; };
constructor(private themeService: NbThemeService, constructor(private themeService: NbThemeService,

View file

@ -5,7 +5,6 @@
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
height: 6rem; height: 6rem;
overflow: visible;
.icon-container { .icon-container {
height: 100%; height: 100%;

View file

@ -4,7 +4,7 @@ import { Component, Input } from '@angular/core';
selector: 'ngx-status-card', selector: 'ngx-status-card',
styleUrls: ['./status-card.component.scss'], styleUrls: ['./status-card.component.scss'],
template: ` template: `
<nb-card (click)="on = !on" [ngClass]="{'off': !on}"> <nb-card matRipple (click)="on = !on" [ngClass]="{'off': !on}">
<div class="icon-container"> <div class="icon-container">
<div class="icon status-{{ type }}"> <div class="icon status-{{ type }}">
<ng-content></ng-content> <ng-content></ng-content>

View file

@ -20,16 +20,16 @@
</div> </div>
<nb-radio-group [(ngModel)]="temperatureMode" name="temperature-mode"> <nb-radio-group [(ngModel)]="temperatureMode" name="temperature-mode">
<nb-radio value="cool"> <nb-radio matRipple value="cool">
<i class="nb-snowy-circled"></i> <i class="nb-snowy-circled"></i>
</nb-radio> </nb-radio>
<nb-radio value="warm"> <nb-radio matRipple value="warm">
<i class="nb-sunny-circled"></i> <i class="nb-sunny-circled"></i>
</nb-radio> </nb-radio>
<nb-radio value="heat"> <nb-radio matRipple value="heat">
<i class="nb-flame-circled"></i> <i class="nb-flame-circled"></i>
</nb-radio> </nb-radio>
<nb-radio value="fan"> <nb-radio matRipple value="fan">
<i class="nb-loop-circled"></i> <i class="nb-loop-circled"></i>
</nb-radio> </nb-radio>
</nb-radio-group> </nb-radio-group>