Material ripple
Splash screen
RTL support
RTL mode
Theme settings panel
PAGE LAYOUT
LAYOUT OPTIONS
{{option[1]}}
Fixed navbar
Fixed footer
Reversed
Collapsed sidenav
THEME
NAVBAR BG
{{option}}
SIDENAV BG
{{option}}
FOOTER BG
{{option}}
Angular Starter
{% if settingsPanel -%}
{% endif %} {% if materialRipple %} {% endif %} {%- if materialRipple and not settingsPanel -%} {% endif %} {% if settingsPanel %} {% endif %} {% if splashScreen %}
CompanyName
{% endif %}
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "angular-starter": { "root": "", "sourceRoot": "src", "projectType": "application", "prefix": "app", "schematics": { "@schematics/angular:component": { "styleext": "scss" } }, "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/angular-starter", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.app.json", "assets": [ "src/favicon.ico", "src/assets" ], "styles": [ "src/styles.scss", {% if not settingsPanel -%} "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/bootstrap{% if style == 'material' %}-material{% endif %}.scss", "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/appwork{% if style == 'material' %}-material{% endif %}.scss", "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-{{theme}}{% if style == 'material' %}-material{% endif %}.scss", "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/colors{% if style == 'material' %}-material{% endif %}.scss", "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/uikit.scss" {%- else -%} { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/appwork.scss", "bundleName": "vendor/styles/appwork", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/appwork-material.scss", "bundleName": "vendor/styles/appwork-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/bootstrap.scss", "bundleName": "vendor/styles/bootstrap", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/bootstrap-material.scss", "bundleName": "vendor/styles/bootstrap-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/colors.scss", "bundleName": "vendor/styles/colors", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/colors-material.scss", "bundleName": "vendor/styles/colors-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/uikit.scss", "bundleName": "vendor/styles/uikit", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-air.scss", "bundleName": "vendor/styles/theme-air", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-air-material.scss", "bundleName": "vendor/styles/theme-air-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-corporate.scss", "bundleName": "vendor/styles/theme-corporate", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-corporate-material.scss", "bundleName": "vendor/styles/theme-corporate-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-cotton.scss", "bundleName": "vendor/styles/theme-cotton", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-cotton-material.scss", "bundleName": "vendor/styles/theme-cotton-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-gradient.scss", "bundleName": "vendor/styles/theme-gradient", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-gradient-material.scss", "bundleName": "vendor/styles/theme-gradient-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-paper.scss", "bundleName": "vendor/styles/theme-paper", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-paper-material.scss", "bundleName": "vendor/styles/theme-paper-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-shadow.scss", "bundleName": "vendor/styles/theme-shadow", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-shadow-material.scss", "bundleName": "vendor/styles/theme-shadow-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-soft.scss", "bundleName": "vendor/styles/theme-soft", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-soft-material.scss", "bundleName": "vendor/styles/theme-soft-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-sunrise.scss", "bundleName": "vendor/styles/theme-sunrise", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-sunrise-material.scss", "bundleName": "vendor/styles/theme-sunrise-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-twitlight.scss", "bundleName": "vendor/styles/theme-twitlight", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-twitlight-material.scss", "bundleName": "vendor/styles/theme-twitlight-material", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-vibrant.scss", "bundleName": "vendor/styles/theme-vibrant", "lazy": true }, { "input": "src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-vibrant-material.scss", "bundleName": "vendor/styles/theme-vibrant-material", "lazy": true } {%- endif %} ], "scripts": [] }, "configurations": { "production": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ], "optimization": true, "outputHashing": "all", "sourceMap": false, "extractCss": true, "namedChunks": false, "aot": true, "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true }, "serve": { "extractCss": true, "namedChunks": true, "vendorChunk": true, "commonChunk": true, "verbose": false } } }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "angular-starter:build:serve" }, "configurations": { "production": { "browserTarget": "angular-starter:build:production" } } }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { "browserTarget": "angular-starter:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.spec.json", "karmaConfig": "src/karma.conf.js", "styles": [ "src/styles.scss" ], "scripts": [], "assets": [ "src/favicon.ico", "src/assets" ] } }, "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { "tsConfig": [ "src/tsconfig.app.json", "src/tsconfig.spec.json" ], "exclude": [ "**/node_modules/**" ] } } } }, "angular-starter-e2e": { "root": "e2e/", "projectType": "application", "architect": { "e2e": { "builder": "@angular-devkit/build-angular:protractor", "options": { "protractorConfig": "e2e/protractor.conf.js", "devServerTarget": "angular-starter:serve" } }, "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { "tsConfig": "e2e/tsconfig.e2e.json", "exclude": [ "**/node_modules/**" ] } } } } }, "defaultProject": "angular-starter" }
import { Component } from '@angular/core'; import { Router, Event as RouterEvent, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router'; import { AppService } from './app.service'; import { LayoutService } from './layout/layout.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styles: [':host { display: block; }'] }) export class AppComponent { constructor(private router: Router, private appService: AppService, private layoutService: LayoutService) { // Subscribe to router events to handle page transition this.router.events.subscribe(this.navigationInterceptor.bind(this)); // Disable animations and transitions in IE10 to increase performance if (typeof document['documentMode'] === 'number' && document['documentMode'] < 11) { const style = document.createElement('style'); style.textContent = ` * { -ms-animation: none !important; animation: none !important; -ms-transition: none !important; transition: none !important; }`; document.head.appendChild(style); } } private navigationInterceptor(e: RouterEvent) { if (e instanceof NavigationStart) { // Set loading state document.body.classList.add('app-loading'); } if (e instanceof NavigationEnd) { // Scroll to top of the page this.appService.scrollTop(0, 0); } if (e instanceof NavigationEnd || e instanceof NavigationCancel || e instanceof NavigationError) { // On small screens collapse sidenav if (this.layoutService.isSmallScreen() && !this.layoutService.isCollapsed()) { setTimeout(() => this.layoutService.setCollapsed(true, true), 10); } // Remove loading state document.body.classList.remove('app-loading'); {%- if splashScreen %} // Remove initial splash screen const splashScreen = document.querySelector('.app-splash-screen'); if (splashScreen) { splashScreen['style'].opacity = 0; setTimeout(() => splashScreen && splashScreen.parentNode.removeChild(splashScreen), 300); } {%- endif %} } } }
import { BrowserModule, Title } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; // ******************************************************************************* // NgBootstrap import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; // ******************************************************************************* // App import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { AppService } from './app.service'; import { LayoutModule } from './layout/layout.module'; {% if settingsPanel -%} import { ThemeSettingsModule } from '../vendor/libs/theme-settings/theme-settings.module'; {%- endif %} // ******************************************************************************* // Pages import { HomeComponent } from './home/home.component'; import { Page2Component } from './page-2/page-2.component'; // ******************************************************************************* // @NgModule({ declarations: [ AppComponent, // Pages HomeComponent, Page2Component ], imports: [ BrowserModule, NgbModule.forRoot(), // App AppRoutingModule, LayoutModule{% if settingsPanel -%}, ThemeSettingsModule {%- endif %} ], providers: [ Title, AppService ], bootstrap: [ AppComponent ] }) export class AppModule {}
import { Injectable } from '@angular/core'; import { Title } from '@angular/platform-browser'; {%- if settingsPanel %} import { ThemeSettingsService } from '../vendor/libs/theme-settings/theme-settings.service'; {%- endif %} @Injectable() export class AppService { {% if settingsPanel -%} constructor(private titleService: Title, private themeSettingsService: ThemeSettingsService) {} {%- else -%} constructor(private titleService: Title) {} {%- endif %} // Set page title set pageTitle(value: string) { this.titleService.setTitle(`${value} - Angular Starter`); } // Check for RTL layout get isRTL() { return document.documentElement.getAttribute('dir') === 'rtl' || document.body.getAttribute('dir') === 'rtl'; } // Check if IE10 get isIE10() { return typeof document['documentMode'] === 'number' && document['documentMode'] === 10; } // Layout navbar color get layoutNavbarBg() { {% if settingsPanel -%} return this.themeSettingsService.getOption('navbarBg') || '{{navbarBg}}'; {%- else -%} return '{{navbarBg}}'; {%- endif %} } // Layout sidenav color get layoutSidenavBg() { {% if settingsPanel -%} return this.themeSettingsService.getOption('sidenavBg') || '{{sidenavBg}}'; {%- else -%} return '{{sidenavBg}}'; {%- endif %} } // Layout footer color get layoutFooterBg() { {% if settingsPanel -%} return this.themeSettingsService.getOption('footerBg') || '{{footerBg}}'; {%- else -%} return '{{footerBg}}'; {%- endif %} } // Animate scrollTop scrollTop(to: number, duration: number, element = document.scrollingElement || document.documentElement) { if (element.scrollTop === to) { return; } const start = element.scrollTop; const change = to - start; const startDate = +new Date(); // t = current time; b = start value; c = change in value; d = duration const easeInOutQuad = (t, b, c, d) => { t /= d / 2; if (t < 1) { return c / 2 * t * t + b; } t--; return -c / 2 * (t * (t - 2) - 1) + b; }; const animateScroll = function() { const currentDate = +new Date(); const currentTime = currentDate - startDate; element.scrollTop = parseInt(easeInOutQuad(currentTime, start, change, duration), 10); if (currentTime < duration) { requestAnimationFrame(animateScroll); } else { element.scrollTop = to; } }; animateScroll(); } }
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; // ******************************************************************************* // Layouts import { {{layoutClass(pageLayout)}} } from './layout/{{prefixLayout(pageLayout)}}/{{prefixLayout(pageLayout)}}.component'; // ******************************************************************************* // Pages import { HomeComponent } from './home/home.component'; import { Page2Component } from './page-2/page-2.component'; // ******************************************************************************* // Routes const routes: Routes = [ { path: '', component: {{layoutClass(pageLayout)}}, pathMatch: 'full', children: [ { path: '', component: HomeComponent }, ]}, { path: 'page-2', component: {{layoutClass(pageLayout)}}, children: [ { path: '', component: Page2Component }, ]} ]; // ******************************************************************************* // @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule {}