mirror of
https://github.com/akveo/ngx-admin.git
synced 2025-12-19 08:50:13 +01:00
Implement ripple effect for material themes
This commit is contained in:
parent
b03633ba9f
commit
690bd322c2
12 changed files with 70 additions and 19 deletions
20
package-lock.json
generated
20
package-lock.json
generated
|
|
@ -363,18 +363,17 @@
|
||||||
"integrity": "sha512-zTCgrIAA9FYPMbqqpQnoNltiLR58q0FMfzP2t96q/1tjyVy/Y/IaNgVQ7eL0HeQ0nG6IAzQ1HVx8Xeneg4Yj5Q=="
|
"integrity": "sha512-zTCgrIAA9FYPMbqqpQnoNltiLR58q0FMfzP2t96q/1tjyVy/Y/IaNgVQ7eL0HeQ0nG6IAzQ1HVx8Xeneg4Yj5Q=="
|
||||||
},
|
},
|
||||||
"@angular/cdk": {
|
"@angular/cdk": {
|
||||||
"version": "8.0.0",
|
"version": "9.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-8.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-9.1.0.tgz",
|
||||||
"integrity": "sha512-2vsRWEHNARe0iRmqgzvM67gwfRy+aKvdef4Qu9L+ndSsTrrZT3tSgG8SMn1v9SfBHnx5G8mo4d1AMquXG69AuQ==",
|
"integrity": "sha512-qKpAudJx9z0MD+ADptS0OZViJBTA49+JCKym0hPQUkcB9Po4Al6gu6oZ1VSXV5Ln3T84z9aAw/AhUGP/YCFNSQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"parse5": "^5.0.0",
|
"parse5": "^5.0.0"
|
||||||
"tslib": "^1.7.1"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"parse5": {
|
"parse5": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
|
||||||
"integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
|
"integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
|
||||||
"optional": true
|
"optional": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -857,6 +856,11 @@
|
||||||
"integrity": "sha512-Q/kFQV4mjZ/Mpx6GksriM5lingjX73EwtVc79AfVMA76Pv5XqfYQZuti6tk7DvYQD89sv1Z/iN2di+ZLKsSTnw==",
|
"integrity": "sha512-Q/kFQV4mjZ/Mpx6GksriM5lingjX73EwtVc79AfVMA76Pv5XqfYQZuti6tk7DvYQD89sv1Z/iN2di+ZLKsSTnw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@angular/material": {
|
||||||
|
"version": "9.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/material/-/material-9.1.0.tgz",
|
||||||
|
"integrity": "sha512-KjA1ARoZ1vBg4jUH1y39muynxAFvkD8QZFGKH8Nh4zXW5pOP/7NyjokxXsNx5qSBCq/6ac2xBxCrCYJN7HmoDw=="
|
||||||
|
},
|
||||||
"@angular/platform-browser": {
|
"@angular/platform-browser": {
|
||||||
"version": "9.0.4",
|
"version": "9.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.0.4.tgz",
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,13 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^9.0.4",
|
"@angular/animations": "^9.0.4",
|
||||||
"@angular/cdk": "^8.0.0",
|
"@angular/cdk": "^9.1.0",
|
||||||
"@angular/common": "^9.0.4",
|
"@angular/common": "^9.0.4",
|
||||||
"@angular/compiler": "^9.0.4",
|
"@angular/compiler": "^9.0.4",
|
||||||
"@angular/core": "^9.0.4",
|
"@angular/core": "^9.0.4",
|
||||||
"@angular/forms": "^9.0.4",
|
"@angular/forms": "^9.0.4",
|
||||||
"@angular/google-maps": "^9.1.0",
|
"@angular/google-maps": "^9.1.0",
|
||||||
|
"@angular/material": "^9.1.0",
|
||||||
"@angular/platform-browser": "^9.0.4",
|
"@angular/platform-browser": "^9.0.4",
|
||||||
"@angular/platform-browser-dynamic": "^9.0.4",
|
"@angular/platform-browser-dynamic": "^9.0.4",
|
||||||
"@angular/router": "^9.0.4",
|
"@angular/router": "^9.0.4",
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
11
src/app/@core/utils/ripple.service.ts
Normal file
11
src/app/@core/utils/ripple.service.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
21
src/app/@theme/styles/_ripple.scss
Normal file
21
src/app/@theme/styles/_ripple.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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%;
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue