From 72b9633820cdf3de5484246010bc081abc0bbad7 Mon Sep 17 00:00:00 2001 From: nixa <4dmitr@gmail.com> Date: Tue, 5 Mar 2019 12:54:08 +0300 Subject: [PATCH 01/33] feat(theme): add NbIcon component (WIP) --- package-lock.json | 5 + package.json | 3 +- .../icon/_icon.component.theme.scss | 31 ++++ .../theme/components/icon/icon.component.scss | 3 + .../theme/components/icon/icon.component.ts | 158 ++++++++++++++++++ .../theme/components/icon/icon.module.ts | 24 +++ .../theme/components/icon/icon.spec.ts | 10 ++ src/framework/theme/index.ts | 2 + .../theme/styles/global/_components.scss | 2 + .../theme/styles/themes/_default.scss | 9 + .../with-layout/icon/icon-routing.module.ts | 23 +++ .../icon/icon-showcase.component.html | 11 ++ .../icon/icon-showcase.component.ts | 15 ++ .../with-layout/icon/icon.module.ts | 26 +++ .../with-layout/with-layout-routing.module.ts | 4 + 15 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 src/framework/theme/components/icon/_icon.component.theme.scss create mode 100644 src/framework/theme/components/icon/icon.component.scss create mode 100644 src/framework/theme/components/icon/icon.component.ts create mode 100644 src/framework/theme/components/icon/icon.module.ts create mode 100644 src/framework/theme/components/icon/icon.spec.ts create mode 100644 src/playground/with-layout/icon/icon-routing.module.ts create mode 100644 src/playground/with-layout/icon/icon-showcase.component.html create mode 100644 src/playground/with-layout/icon/icon-showcase.component.ts create mode 100644 src/playground/with-layout/icon/icon.module.ts diff --git a/package-lock.json b/package-lock.json index ba3a67284d..1911f5fc61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5893,6 +5893,11 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, + "eva-icons": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/eva-icons/-/eva-icons-1.1.1.tgz", + "integrity": "sha512-Uf7JQMA1lWQLLtHuk1lbMlwP4i3W0jjTy5SCYBGeR6DLPub5Ls2QiJlVT59llphVObXSVwaMuofevwgUZWf1CQ==" + }, "event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", diff --git a/package.json b/package.json index 2cad45542b..8f65e44363 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "core-js": "2.5.7", "date-fns": ">=2.0.0-alpha.16 <=2.0.0-alpha.27", "docsearch.js": "^2.5.2", + "eva-icons": "^1.1.1", "gulp-bump": "2.7.0", "highlight.js": "9.12.0", "intersection-observer": "0.5.0", @@ -174,4 +175,4 @@ "uglifyjs-webpack-plugin": "1.1.5" }, "schematics": "./schematics/dist/collection.json" -} \ No newline at end of file +} diff --git a/src/framework/theme/components/icon/_icon.component.theme.scss b/src/framework/theme/components/icon/_icon.component.theme.scss new file mode 100644 index 0000000000..69810fd104 --- /dev/null +++ b/src/framework/theme/components/icon/_icon.component.theme.scss @@ -0,0 +1,31 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +@mixin nb-icon-theme() { + nb-icon { + font-size: nb-theme(icon-font-size); + line-height: nb-theme(icon-line-height); + width: nb-theme(icon-width); + height: nb-theme(icon-height); + + &.primary-icon { + color: nb-theme(icon-primary-fg); + } + &.info-icon { + color: nb-theme(icon-info-fg); + } + &.success-icon { + color: nb-theme(icon-success-fg); + } + &.warning-icon { + color: nb-theme(icon-warning-fg); + } + &.danger-icon { + color: nb-theme(icon-danger-fg); + } + } +} + diff --git a/src/framework/theme/components/icon/icon.component.scss b/src/framework/theme/components/icon/icon.component.scss new file mode 100644 index 0000000000..48bb062ea7 --- /dev/null +++ b/src/framework/theme/components/icon/icon.component.scss @@ -0,0 +1,3 @@ +:host { + display: inline-block; +} diff --git a/src/framework/theme/components/icon/icon.component.ts b/src/framework/theme/components/icon/icon.component.ts new file mode 100644 index 0000000000..51d3f98498 --- /dev/null +++ b/src/framework/theme/components/icon/icon.component.ts @@ -0,0 +1,158 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { Component, Input, HostBinding } from '@angular/core'; +import {DomSanitizer, SafeHtml} from '@angular/platform-browser'; +import { icons } from 'eva-icons'; + +/** + * Icon component. + * + * Basic alert example: + * @stacked-example(Showcase, alert/alert-showcase.component) + * + * Alert configuration: + * + * ```html + * + * You have been successfully authenticated! + * + * ``` + * ### Installation + * + * Import `NbButtonModule` to your feature module. + * ```ts + * @NgModule({ + * imports: [ + * // ... + * NbAlertModule, + * ], + * }) + * export class PageModule { } + * ``` + * ### Usage + * + * Alert could additionally have a `close` button when `closable` property is set: + * ```html + * + * You have been successfully authenticated! + * + * ``` + * + * Colored alerts could be simply configured by providing a `status` property: + * @stacked-example(Colored Alert, alert/alert-colors.component) + * + * It is also possible to assign an `accent` property for a slight alert highlight + * as well as combine it with `status`: + * @stacked-example(Accent Alert, alert/alert-accents.component) + * + * And `outline` property: + * @stacked-example(Outline Alert, alert/alert-outline.component) + * + * @additional-example(Multiple Sizes, alert/alert-sizes.component) + * + * @styles + * + * alert-font-size: + * alert-line-height: + * alert-font-weight: + * alert-fg: + * alert-outline-fg: + * alert-bg: + * alert-active-bg: + * alert-disabled-bg: + * alert-disabled-fg: + * alert-primary-bg: + * alert-info-bg: + * alert-success-bg: + * alert-warning-bg: + * alert-danger-bg: + * alert-height-xxsmall: + * alert-height-xsmall: + * alert-height-small: + * alert-height-medium: + * alert-height-large: + * alert-height-xlarge: + * alert-height-xxlarge: + * alert-shadow: + * alert-border-radius: + * alert-padding: + * alert-closable-padding: + * alert-button-padding: + * alert-margin: + */ +@Component({ + selector: 'nb-icon', + styleUrls: [`./icon.component.scss`], + template: ` + {{ iconSVG }} + `, +}) +export class NbIconComponent { + + static readonly STATUS_PRIMARY = 'primary'; + static readonly STATUS_INFO = 'info'; + static readonly STATUS_SUCCESS = 'success'; + static readonly STATUS_WARNING = 'warning'; + static readonly STATUS_DANGER = 'danger'; + + @HostBinding('innerHtml') + iconSVG: SafeHtml; + + @Input() + set icon(icon: string) { + this.iconSVG = this.sanitizer.bypassSecurityTrustHtml(icons[icon].toSvg({ + width: '100%', + height: '100%', + fill: 'currentColor', + })); + } + + /** + * Icon status (adds specific styles): + * primary, info, success, warning, danger + * @param {string} val + */ + @Input() status: string; + + @HostBinding('class.primary-icon') + get primary() { + return this.status === NbIconComponent.STATUS_PRIMARY; + } + + @HostBinding('class.info-icon') + get info() { + return this.status === NbIconComponent.STATUS_INFO; + } + + @HostBinding('class.success-icon') + get success() { + return this.status === NbIconComponent.STATUS_SUCCESS; + } + + @HostBinding('class.warning-icon') + get warning() { + return this.status === NbIconComponent.STATUS_WARNING; + } + + @HostBinding('class.danger-icon') + get danger() { + return this.status === NbIconComponent.STATUS_DANGER; + } + + /** + * Icon status (adds specific styles): + * primary, info, success, warning, danger + * @param {string} val + */ + @Input('status') + private set setStatus(val: string) { + this.status = val; + } + + constructor(private sanitizer: DomSanitizer) { + } +} diff --git a/src/framework/theme/components/icon/icon.module.ts b/src/framework/theme/components/icon/icon.module.ts new file mode 100644 index 0000000000..da123c3944 --- /dev/null +++ b/src/framework/theme/components/icon/icon.module.ts @@ -0,0 +1,24 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { NbIconComponent } from './icon.component'; + +@NgModule({ + imports: [ + CommonModule, + ], + declarations: [ + NbIconComponent, + ], + exports: [ + NbIconComponent, + ], +}) +export class NbIconModule { +} diff --git a/src/framework/theme/components/icon/icon.spec.ts b/src/framework/theme/components/icon/icon.spec.ts new file mode 100644 index 0000000000..de6b8af7e8 --- /dev/null +++ b/src/framework/theme/components/icon/icon.spec.ts @@ -0,0 +1,10 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +// import { ComponentFixture, TestBed } from '@angular/core/testing'; + +describe('Component: NbIcon', () => { +}); diff --git a/src/framework/theme/index.ts b/src/framework/theme/index.ts index 7f54b80c6b..3f1877ff73 100644 --- a/src/framework/theme/index.ts +++ b/src/framework/theme/index.ts @@ -99,3 +99,5 @@ export * from './components/tree-grid/data-source/tree-grid-data.service'; export * from './components/tree-grid/data-source/tree-grid-filter.service'; export * from './components/tree-grid/data-source/tree-grid.service'; export * from './components/tree-grid/data-source/tree-grid-sort.service'; +export * from './components/icon/icon.module'; +export * from './components/icon/icon.component'; diff --git a/src/framework/theme/styles/global/_components.scss b/src/framework/theme/styles/global/_components.scss index 77fdd6cdf1..66972c1269 100644 --- a/src/framework/theme/styles/global/_components.scss +++ b/src/framework/theme/styles/global/_components.scss @@ -38,6 +38,7 @@ @import '../../components/datepicker/datepicker-container.component.theme'; @import '../../components/radio/radio.component.theme'; @import '../../components/tree-grid/tree-grid.component.theme'; +@import '../../components/icon/icon.component.theme'; @mixin nb-theme-components() { @@ -75,4 +76,5 @@ @include nb-datepicker-theme(); @include nb-radio-theme(); @include nb-tree-grid-theme(); + @include nb-icon-theme(); } diff --git a/src/framework/theme/styles/themes/_default.scss b/src/framework/theme/styles/themes/_default.scss index 2fe6c8636c..59537acae1 100644 --- a/src/framework/theme/styles/themes/_default.scss +++ b/src/framework/theme/styles/themes/_default.scss @@ -696,6 +696,15 @@ $theme: ( tree-grid-row-hover-bg: color-bg, tree-grid-sort-header-button-color: color-fg-text, tree-grid-icon-color: color-fg-text, + + icon-font-size: 1.5rem, + icon-width: icon-font-size, + icon-height: icon-font-size, + icon-primary-fg: color-primary, + icon-info-fg: color-info, + icon-success-fg: color-success, + icon-warning-fg: color-warning, + icon-danger-fg: color-danger, ); // register the theme diff --git a/src/playground/with-layout/icon/icon-routing.module.ts b/src/playground/with-layout/icon/icon-routing.module.ts new file mode 100644 index 0000000000..2ab0a92831 --- /dev/null +++ b/src/playground/with-layout/icon/icon-routing.module.ts @@ -0,0 +1,23 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { NgModule } from '@angular/core'; +import { RouterModule, Route } from '@angular/router'; + +import { IconShowcaseComponent } from './icon-showcase.component'; + +const routes: Route[] = [ + { + path: 'icon-showcase.component', + component: IconShowcaseComponent, + }, +]; + +@NgModule({ + imports: [ RouterModule.forChild(routes) ], + exports: [ RouterModule ], +}) +export class IconRoutingModule {} diff --git a/src/playground/with-layout/icon/icon-showcase.component.html b/src/playground/with-layout/icon/icon-showcase.component.html new file mode 100644 index 0000000000..9c83d37ba2 --- /dev/null +++ b/src/playground/with-layout/icon/icon-showcase.component.html @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/playground/with-layout/icon/icon-showcase.component.ts b/src/playground/with-layout/icon/icon-showcase.component.ts new file mode 100644 index 0000000000..f0e3da405f --- /dev/null +++ b/src/playground/with-layout/icon/icon-showcase.component.ts @@ -0,0 +1,15 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + selector: 'nb-icon-showcase', + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './icon-showcase.component.html', +}) +export class IconShowcaseComponent { +} diff --git a/src/playground/with-layout/icon/icon.module.ts b/src/playground/with-layout/icon/icon.module.ts new file mode 100644 index 0000000000..b1451af05c --- /dev/null +++ b/src/playground/with-layout/icon/icon.module.ts @@ -0,0 +1,26 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { NbIconModule, NbButtonModule, NbCardModule } from '@nebular/theme'; + +import { IconRoutingModule } from './icon-routing.module'; +import { IconShowcaseComponent } from './icon-showcase.component'; + +@NgModule({ + declarations: [ + IconShowcaseComponent, + ], + imports: [ + CommonModule, + NbIconModule, + NbButtonModule, + NbCardModule, + IconRoutingModule, + ], +}) +export class IconModule {} diff --git a/src/playground/with-layout/with-layout-routing.module.ts b/src/playground/with-layout/with-layout-routing.module.ts index 71edc66665..24e79f8b88 100644 --- a/src/playground/with-layout/with-layout-routing.module.ts +++ b/src/playground/with-layout/with-layout-routing.module.ts @@ -153,6 +153,10 @@ const routes: Route[] = [ path: 'tree-grid', loadChildren: './tree-grid/tree-grid.module#TreeGridModule', }, + { + path: 'icon', + loadChildren: './icon/icon.module#IconModule', + }, ], }, ]; From a771541e22c2e0120bae69291c7f2a2864f584b1 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Tue, 5 Mar 2019 20:54:27 +0300 Subject: [PATCH 02/33] feat(theme): add icon service WIP --- src/app/playground-components.ts | 11 ++ .../components/icon/eva-icons.service.ts | 23 ++++ .../components/icon/icon-library.service.ts | 126 ++++++++++++++++++ .../theme/components/icon/icon.component.ts | 17 ++- .../theme/components/icon/icon.module.ts | 6 + src/framework/theme/index.ts | 1 + 6 files changed, 177 insertions(+), 7 deletions(-) create mode 100644 src/framework/theme/components/icon/eva-icons.service.ts create mode 100644 src/framework/theme/components/icon/icon-library.service.ts diff --git a/src/app/playground-components.ts b/src/app/playground-components.ts index 161bdc87f3..f2854d482c 100644 --- a/src/app/playground-components.ts +++ b/src/app/playground-components.ts @@ -1309,6 +1309,17 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [ }, ], }, + { + path: 'icon', + children: [ + { + path: 'icon-showcase.component', + link: '/icon/icon-showcase.component', + component: 'IconShowcaseComponent', + name: 'Icon Showcase', + }, + ], + }, { path: 'context-menu', children: [ diff --git a/src/framework/theme/components/icon/eva-icons.service.ts b/src/framework/theme/components/icon/eva-icons.service.ts new file mode 100644 index 0000000000..c2ada82ab8 --- /dev/null +++ b/src/framework/theme/components/icon/eva-icons.service.ts @@ -0,0 +1,23 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { Injectable } from '@angular/core'; +import { NbIconLibraryService } from './icon-library.service'; +import { icons } from 'eva-icons'; + +/** + * NbEvaIcons is a services that registers `eva-icons` as Nebular SVG icons library. + */ +@Injectable() +export class NbEvaIconsService { + + private NAME = 'eva'; + + constructor(private iconLibrary: NbIconLibraryService) { + this.iconLibrary.registerSvgPack(this.NAME, new Map(Object.entries(icons))); + this.iconLibrary.setDefaultPack(this.NAME); + } +} diff --git a/src/framework/theme/components/icon/icon-library.service.ts b/src/framework/theme/components/icon/icon-library.service.ts new file mode 100644 index 0000000000..f41120cf47 --- /dev/null +++ b/src/framework/theme/components/icon/icon-library.service.ts @@ -0,0 +1,126 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { Injectable } from '@angular/core'; + +export type NbIcon = NbIconDefinition | string; + +export class NbIconDefinition { + icon: string; + pack?: string; +} + +export type NbIcons = Map; + +export enum NbIconPackType { + SVG = 'svg', + FONT = 'font', +} + +export interface NbIconPack { + name: string; + type: NbIconPackType; + icons?: NbIcons; + classPrefix?: string; +} + +function throwPackNotFoundError(name: string) { + throw Error(`Pack '${name}' is not registered`); +} + +function throwIconNotFoundError(name: string, pack: string) { + throw Error(`Icon '${name}' is not registered in pack '${pack}'`); +} + +/** + * NbIconLibraryService + */ +@Injectable() +export class NbIconLibraryService { + + protected packs: Map = new Map(); + protected defaultPack: NbIconPack; + + registerSvgPack(name: string, icons: NbIcons) { + this.packs.set(name, { + name, + icons, + type: NbIconPackType.SVG, + }); + } + + registerFontPack(name: string, classPrefix: string) { + this.packs.set(name, { + name, + classPrefix, + type: NbIconPackType.FONT, + }); + } + + setDefaultPack(name: string) { + if (!this.packs.has(name)) { + throwPackNotFoundError(name); + } + + this.defaultPack = this.packs.get(name); + } + + + /** + * TODO: animations? fill? etc + * @param name + * @param pack + */ + getSvgIcon(name: string, pack?: string) { + + const iconsPack = this.getPackOrDefault(pack); + + if (iconsPack.type !== NbIconPackType.SVG) { + throw Error(`Pack '${iconsPack.name}' is not an SVG Pack and its type is '${iconsPack.type}'`); + } + + return this.getIconFromPack(name, iconsPack); + } + + getFontIcon(name: string, pack?: string) { + const iconsPack = this.getPackOrDefault(pack); + + if (iconsPack.type !== NbIconPackType.FONT) { + throw Error(`Pack '${iconsPack.name}' is not a Font Pack and its type is '${iconsPack.type}'`); + } + + return this.getIconFromPack(name, iconsPack); + } + + + getIcon(name: string, pack?: string) { + + const iconsPack = this.getPackOrDefault(pack); + + if (iconsPack.type === NbIconPackType.SVG) { + return this.getSvgIcon(name, pack); + } + + return this.getFontIcon(name, pack); + } + + protected getPackOrDefault(name: string) { + const iconsPack = name ? this.packs.get(name) : this.defaultPack; + + if (!iconsPack) { + throwPackNotFoundError(name); + } + return iconsPack; + } + + protected getIconFromPack(name: string, pack: NbIconPack) { + if (!pack.icons.has(name)) { + throwIconNotFoundError(name, pack.name); + } + + return pack.icons.get(name); + } +} diff --git a/src/framework/theme/components/icon/icon.component.ts b/src/framework/theme/components/icon/icon.component.ts index 51d3f98498..668aa95b7b 100644 --- a/src/framework/theme/components/icon/icon.component.ts +++ b/src/framework/theme/components/icon/icon.component.ts @@ -6,7 +6,8 @@ import { Component, Input, HostBinding } from '@angular/core'; import {DomSanitizer, SafeHtml} from '@angular/platform-browser'; -import { icons } from 'eva-icons'; + +import { NbIconLibraryService } from './icon-library.service'; /** * Icon component. @@ -104,11 +105,13 @@ export class NbIconComponent { @Input() set icon(icon: string) { - this.iconSVG = this.sanitizer.bypassSecurityTrustHtml(icons[icon].toSvg({ - width: '100%', - height: '100%', - fill: 'currentColor', - })); + // this.iconSVG = this.sanitizer.bypassSecurityTrustHtml(icons[icon].toSvg({ + // width: '100%', + // height: '100%', + // fill: 'currentColor', + // })); + + this.iconSVG = this.sanitizer.bypassSecurityTrustHtml(this.iconLibrary.getSvgIcon(icon)); } /** @@ -153,6 +156,6 @@ export class NbIconComponent { this.status = val; } - constructor(private sanitizer: DomSanitizer) { + constructor(private sanitizer: DomSanitizer, private iconLibrary: NbIconLibraryService) { } } diff --git a/src/framework/theme/components/icon/icon.module.ts b/src/framework/theme/components/icon/icon.module.ts index da123c3944..0d3f13b15d 100644 --- a/src/framework/theme/components/icon/icon.module.ts +++ b/src/framework/theme/components/icon/icon.module.ts @@ -8,6 +8,8 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NbIconComponent } from './icon.component'; +import { NbIconLibraryService } from './icon-library.service'; +import { NbEvaIconsService } from './eva-icons.service'; @NgModule({ imports: [ @@ -16,6 +18,10 @@ import { NbIconComponent } from './icon.component'; declarations: [ NbIconComponent, ], + providers: [ + NbIconLibraryService, + NbEvaIconsService, + ], exports: [ NbIconComponent, ], diff --git a/src/framework/theme/index.ts b/src/framework/theme/index.ts index 3f1877ff73..29cedfb4bc 100644 --- a/src/framework/theme/index.ts +++ b/src/framework/theme/index.ts @@ -101,3 +101,4 @@ export * from './components/tree-grid/data-source/tree-grid.service'; export * from './components/tree-grid/data-source/tree-grid-sort.service'; export * from './components/icon/icon.module'; export * from './components/icon/icon.component'; +export * from './components/icon/icon-library.service'; From e74a47452a950e41f0576d62773cc7b077e7b22d Mon Sep 17 00:00:00 2001 From: nixa <4dmitr@gmail.com> Date: Tue, 19 Mar 2019 16:09:28 +0300 Subject: [PATCH 03/33] refactor --- src/framework/eva-icons/README.md | 1 + src/framework/eva-icons/eva-icons.module.ts | 63 +++++++++++++++ src/framework/eva-icons/index.ts | 7 ++ src/framework/eva-icons/package.json | 31 ++++++++ .../components/icon/eva-icons.service.ts | 23 ------ .../theme/components/icon/icon.component.ts | 78 +++++++++++------- .../theme/components/icon/icon.module.ts | 6 -- src/framework/theme/index.ts | 2 +- .../theme/services/icons/icon-pack.ts | 23 ++++++ src/framework/theme/services/icons/icon.ts | 42 ++++++++++ .../icons/icons-library.ts} | 79 ++++++++++--------- src/framework/theme/services/icons/index.ts | 3 + src/framework/theme/theme.module.ts | 2 + .../icon/icon-showcase.component.html | 12 +-- .../icon/icon-showcase.component.ts | 19 +++++ .../with-layout/icon/icon.module.ts | 2 + 16 files changed, 291 insertions(+), 102 deletions(-) create mode 100644 src/framework/eva-icons/README.md create mode 100644 src/framework/eva-icons/eva-icons.module.ts create mode 100644 src/framework/eva-icons/index.ts create mode 100644 src/framework/eva-icons/package.json delete mode 100644 src/framework/theme/components/icon/eva-icons.service.ts create mode 100644 src/framework/theme/services/icons/icon-pack.ts create mode 100644 src/framework/theme/services/icons/icon.ts rename src/framework/theme/{components/icon/icon-library.service.ts => services/icons/icons-library.ts} (53%) create mode 100644 src/framework/theme/services/icons/index.ts diff --git a/src/framework/eva-icons/README.md b/src/framework/eva-icons/README.md new file mode 100644 index 0000000000..6b7e7c8727 --- /dev/null +++ b/src/framework/eva-icons/README.md @@ -0,0 +1 @@ +### @nebular/eva-icons module, more details https://akveo.github.io/nebular/ diff --git a/src/framework/eva-icons/eva-icons.module.ts b/src/framework/eva-icons/eva-icons.module.ts new file mode 100644 index 0000000000..d10aa545ac --- /dev/null +++ b/src/framework/eva-icons/eva-icons.module.ts @@ -0,0 +1,63 @@ +/* + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { NgModule } from '@angular/core'; +import { NbIconsLibrary, NbSvgIcon, NbIconPackParams, NbIcons } from '@nebular/theme'; +import { icons } from 'eva-icons'; + +interface NbOriginalEvaIcon { + toSvg(options: NbEvaIconOptions); +} + +export interface NbEvaIconOptions { + width: string, + height: string, + fill: string, + animation: { + type: string, + hover: boolean, + infinite: boolean, + }, +} + +export class NbEvaSvgIcon extends NbSvgIcon { + + constructor(protected name, protected content: NbOriginalEvaIcon, protected params: NbIconPackParams) { + super(name, '', params); + } + + render(options): string { + return this.content.toSvg({ + width: '100%', + height: '100%', + fill: 'currentColor', + ...options, + }); + } +} + +@NgModule({}) +export class NbEvaIconsModule { + + private NAME = 'eva'; + + constructor(iconLibrary: NbIconsLibrary) { + iconLibrary.registerSvgPack(this.NAME, this.createIcons()); + iconLibrary.setDefaultPack(this.NAME); + } + + private createIcons(): NbIcons { + return Object + .entries(icons) + .map(([name, icon]) => { + return [name, new NbEvaSvgIcon(name, icon, {packClass: ''})] as [string, NbSvgIcon]; + }) + .reduce((prev, curr) => { + prev[curr[0]] = curr[1]; + return prev; + }, {}); + } +} diff --git a/src/framework/eva-icons/index.ts b/src/framework/eva-icons/index.ts new file mode 100644 index 0000000000..68fc82358e --- /dev/null +++ b/src/framework/eva-icons/index.ts @@ -0,0 +1,7 @@ +/* + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +export * from './eva-icons.module'; diff --git a/src/framework/eva-icons/package.json b/src/framework/eva-icons/package.json new file mode 100644 index 0000000000..252b425019 --- /dev/null +++ b/src/framework/eva-icons/package.json @@ -0,0 +1,31 @@ +{ + "name": "@nebular/eva-icons", + "version": "3.4.0", + "description": "@nebular/eva-icons", + "main": "./bundles/eva-icons.umd.js", + "module": "./index.js", + "typings": "./index.d.ts", + "author": "akveo", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/akveo/nebular.git" + }, + "bugs": { + "url": "https://github.com/akveo/nebular/issues" + }, + "homepage": "https://github.com/akveo/nebular#readme", + "keywords": [ + "angular", + "typescript", + "ng2-admin", + "ngx-admin", + "theme", + "nebular", + "eva-icons" + ], + "peerDependencies": { + "@nebular/theme": "3.4.0", + "eva-icons": "^1.1.1" + } +} diff --git a/src/framework/theme/components/icon/eva-icons.service.ts b/src/framework/theme/components/icon/eva-icons.service.ts deleted file mode 100644 index c2ada82ab8..0000000000 --- a/src/framework/theme/components/icon/eva-icons.service.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @license - * Copyright Akveo. All Rights Reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - */ - -import { Injectable } from '@angular/core'; -import { NbIconLibraryService } from './icon-library.service'; -import { icons } from 'eva-icons'; - -/** - * NbEvaIcons is a services that registers `eva-icons` as Nebular SVG icons library. - */ -@Injectable() -export class NbEvaIconsService { - - private NAME = 'eva'; - - constructor(private iconLibrary: NbIconLibraryService) { - this.iconLibrary.registerSvgPack(this.NAME, new Map(Object.entries(icons))); - this.iconLibrary.setDefaultPack(this.NAME); - } -} diff --git a/src/framework/theme/components/icon/icon.component.ts b/src/framework/theme/components/icon/icon.component.ts index 668aa95b7b..453a80b9bc 100644 --- a/src/framework/theme/components/icon/icon.component.ts +++ b/src/framework/theme/components/icon/icon.component.ts @@ -4,10 +4,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -import { Component, Input, HostBinding } from '@angular/core'; -import {DomSanitizer, SafeHtml} from '@angular/platform-browser'; +import { + Component, + ElementRef, + HostBinding, + Input, + OnChanges, OnInit, + Renderer2, + SimpleChanges, +} from '@angular/core'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; -import { NbIconLibraryService } from './icon-library.service'; +import { NbIconsLibrary } from '../../services/icons'; /** * Icon component. @@ -88,11 +96,9 @@ import { NbIconLibraryService } from './icon-library.service'; @Component({ selector: 'nb-icon', styleUrls: [`./icon.component.scss`], - template: ` - {{ iconSVG }} - `, + template: '', }) -export class NbIconComponent { +export class NbIconComponent implements OnChanges, OnInit { static readonly STATUS_PRIMARY = 'primary'; static readonly STATUS_INFO = 'info'; @@ -100,26 +106,10 @@ export class NbIconComponent { static readonly STATUS_WARNING = 'warning'; static readonly STATUS_DANGER = 'danger'; - @HostBinding('innerHtml') - iconSVG: SafeHtml; - - @Input() - set icon(icon: string) { - // this.iconSVG = this.sanitizer.bypassSecurityTrustHtml(icons[icon].toSvg({ - // width: '100%', - // height: '100%', - // fill: 'currentColor', - // })); - - this.iconSVG = this.sanitizer.bypassSecurityTrustHtml(this.iconLibrary.getSvgIcon(icon)); - } + private iconDef; - /** - * Icon status (adds specific styles): - * primary, info, success, warning, danger - * @param {string} val - */ - @Input() status: string; + @HostBinding('innerHtml') + html: SafeHtml; @HostBinding('class.primary-icon') get primary() { @@ -146,16 +136,44 @@ export class NbIconComponent { return this.status === NbIconComponent.STATUS_DANGER; } + @Input() icon: string; + + @Input() pack: string; + + @Input() options: { [name: string]: any }; + /** * Icon status (adds specific styles): * primary, info, success, warning, danger * @param {string} val */ - @Input('status') - private set setStatus(val: string) { - this.status = val; + @Input() status: string; + + constructor( + private sanitizer: DomSanitizer, + private iconLibrary: NbIconsLibrary, + private el: ElementRef, + private renderer: Renderer2, + ) {} + + ngOnInit() { + this.iconDef = this.renderIcon(this.icon, this.pack, this.options); + } + + ngOnChanges(changes: SimpleChanges) { + if (this.iconDef) { + this.iconDef = this.renderIcon(this.icon, this.pack, this.options); + } } - constructor(private sanitizer: DomSanitizer, private iconLibrary: NbIconLibraryService) { + renderIcon(name: string, pack?: string, options?: { [name: string]: any }) { + const icon = this.iconLibrary.getIcon(name, pack); + + this.html = this.sanitizer.bypassSecurityTrustHtml(icon.icon.render(options)); + + Object.entries(icon.icon.getAttributes(options)).forEach(([attr, value]: [string, string]) => { + this.renderer.setAttribute(this.el.nativeElement, attr, value); + }); + return icon; } } diff --git a/src/framework/theme/components/icon/icon.module.ts b/src/framework/theme/components/icon/icon.module.ts index 0d3f13b15d..da123c3944 100644 --- a/src/framework/theme/components/icon/icon.module.ts +++ b/src/framework/theme/components/icon/icon.module.ts @@ -8,8 +8,6 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NbIconComponent } from './icon.component'; -import { NbIconLibraryService } from './icon-library.service'; -import { NbEvaIconsService } from './eva-icons.service'; @NgModule({ imports: [ @@ -18,10 +16,6 @@ import { NbEvaIconsService } from './eva-icons.service'; declarations: [ NbIconComponent, ], - providers: [ - NbIconLibraryService, - NbEvaIconsService, - ], exports: [ NbIconComponent, ], diff --git a/src/framework/theme/index.ts b/src/framework/theme/index.ts index 29cedfb4bc..67dd535931 100644 --- a/src/framework/theme/index.ts +++ b/src/framework/theme/index.ts @@ -99,6 +99,6 @@ export * from './components/tree-grid/data-source/tree-grid-data.service'; export * from './components/tree-grid/data-source/tree-grid-filter.service'; export * from './components/tree-grid/data-source/tree-grid.service'; export * from './components/tree-grid/data-source/tree-grid-sort.service'; +export * from './services/icons'; export * from './components/icon/icon.module'; export * from './components/icon/icon.component'; -export * from './components/icon/icon-library.service'; diff --git a/src/framework/theme/services/icons/icon-pack.ts b/src/framework/theme/services/icons/icon-pack.ts new file mode 100644 index 0000000000..44193933a2 --- /dev/null +++ b/src/framework/theme/services/icons/icon-pack.ts @@ -0,0 +1,23 @@ +import { NbIcon } from './icon'; + +export interface NbIcons { + [key: string]: NbIcon | string; +} + +export enum NbIconPackType { + SVG = 'svg', + FONT = 'font', +} + +export interface NbIconPackParams { + packClass: string, + iconPrefix?: string, + [name: string]: any, +} + +export interface NbIconPack { + name: string; + type: NbIconPackType; + icons: Map; + params: NbIconPackParams, +} diff --git a/src/framework/theme/services/icons/icon.ts b/src/framework/theme/services/icons/icon.ts new file mode 100644 index 0000000000..c505c21261 --- /dev/null +++ b/src/framework/theme/services/icons/icon.ts @@ -0,0 +1,42 @@ +import { NbIconPackParams } from './icon-pack'; + +export interface NbIconOptions { + [name: string]: any; +} + +export interface NbIcon { + getAttributes(options?: NbIconOptions): any; + render(options?: NbIconOptions): string; +} + +export class NbFontIcon implements NbIcon { + + constructor(protected name, protected content: any, protected params: NbIconPackParams) {} + + getAttributes(options?: NbIconOptions) { + const name = this.params.iconPrefix ? `${this.params.iconPrefix}-${this.name}` : this.name; + + return { + 'class': `${name} ${this.params.packClass}`, + }; + } + + render(options?: NbIconOptions): string { + return ''; + } +} + +export class NbSvgIcon implements NbIcon { + + constructor(protected name, protected content: any, protected params: NbIconPackParams) {} + + getAttributes(options?: NbIconOptions) { + return { + 'class': `${this.params.packClass}`, + }; + } + + render(options?: NbIconOptions): string { + return this.content; + } +} diff --git a/src/framework/theme/components/icon/icon-library.service.ts b/src/framework/theme/services/icons/icons-library.ts similarity index 53% rename from src/framework/theme/components/icon/icon-library.service.ts rename to src/framework/theme/services/icons/icons-library.ts index f41120cf47..928036baa2 100644 --- a/src/framework/theme/components/icon/icon-library.service.ts +++ b/src/framework/theme/services/icons/icons-library.ts @@ -5,30 +5,18 @@ */ import { Injectable } from '@angular/core'; - -export type NbIcon = NbIconDefinition | string; +import { NbIconPack, NbIconPackParams, NbIconPackType, NbIcons } from './icon-pack'; +import { NbFontIcon, NbIcon, NbSvgIcon } from './icon'; export class NbIconDefinition { - icon: string; - pack?: string; -} - -export type NbIcons = Map; - -export enum NbIconPackType { - SVG = 'svg', - FONT = 'font', -} - -export interface NbIconPack { name: string; - type: NbIconPackType; - icons?: NbIcons; - classPrefix?: string; + type: string; + pack: string; + icon: NbIcon; } function throwPackNotFoundError(name: string) { - throw Error(`Pack '${name}' is not registered`); + throw Error(`Icon Pack '${name}' is not registered`); } function throwIconNotFoundError(name: string, pack: string) { @@ -36,26 +24,28 @@ function throwIconNotFoundError(name: string, pack: string) { } /** - * NbIconLibraryService + * NbIconsLibrary */ @Injectable() -export class NbIconLibraryService { +export class NbIconsLibrary { protected packs: Map = new Map(); protected defaultPack: NbIconPack; - registerSvgPack(name: string, icons: NbIcons) { + registerSvgPack(name: string, icons: NbIcons, params: NbIconPackParams = { packClass: '' }) { this.packs.set(name, { name, - icons, + icons: new Map(Object.entries(icons)), + params, type: NbIconPackType.SVG, }); } - registerFontPack(name: string, classPrefix: string) { + registerFontPack(name: string, params: NbIconPackParams = { packClass: '' }) { this.packs.set(name, { name, - classPrefix, + params, + icons: new Map(), type: NbIconPackType.FONT, }); } @@ -68,13 +58,7 @@ export class NbIconLibraryService { this.defaultPack = this.packs.get(name); } - - /** - * TODO: animations? fill? etc - * @param name - * @param pack - */ - getSvgIcon(name: string, pack?: string) { + getSvgIcon(name: string, pack?: string): NbIconDefinition { const iconsPack = this.getPackOrDefault(pack); @@ -82,19 +66,32 @@ export class NbIconLibraryService { throw Error(`Pack '${iconsPack.name}' is not an SVG Pack and its type is '${iconsPack.type}'`); } - return this.getIconFromPack(name, iconsPack); + const icon = this.getIconFromPack(name, iconsPack); + + return { + name, + pack: iconsPack.name, + type: NbIconPackType.SVG, + icon: this.createSvgIcon(name, icon, iconsPack.params), + }; } - getFontIcon(name: string, pack?: string) { + getFontIcon(name: string, pack?: string): NbIconDefinition { const iconsPack = this.getPackOrDefault(pack); if (iconsPack.type !== NbIconPackType.FONT) { throw Error(`Pack '${iconsPack.name}' is not a Font Pack and its type is '${iconsPack.type}'`); } - return this.getIconFromPack(name, iconsPack); - } + const icon = this.getIconFromPack(name, iconsPack, false); + return { + name, + pack: iconsPack.name, + type: NbIconPackType.FONT, + icon: this.createFontIcon(name, icon, iconsPack.params), + }; + } getIcon(name: string, pack?: string) { @@ -107,6 +104,14 @@ export class NbIconLibraryService { return this.getFontIcon(name, pack); } + protected createSvgIcon(name: string, content: NbIcon | string, params: NbIconPackParams) { + return content instanceof NbSvgIcon ? content : new NbSvgIcon(name, content, params); + } + + protected createFontIcon(name: string, content: NbIcon | string, params: NbIconPackParams) { + return content instanceof NbFontIcon ? content : new NbFontIcon(name, content, params); + } + protected getPackOrDefault(name: string) { const iconsPack = name ? this.packs.get(name) : this.defaultPack; @@ -116,8 +121,8 @@ export class NbIconLibraryService { return iconsPack; } - protected getIconFromPack(name: string, pack: NbIconPack) { - if (!pack.icons.has(name)) { + protected getIconFromPack(name: string, pack: NbIconPack, shouldThrow = true) { + if (shouldThrow && !pack.icons.has(name)) { throwIconNotFoundError(name, pack.name); } diff --git a/src/framework/theme/services/icons/index.ts b/src/framework/theme/services/icons/index.ts new file mode 100644 index 0000000000..c8611559f7 --- /dev/null +++ b/src/framework/theme/services/icons/index.ts @@ -0,0 +1,3 @@ +export * from './icon'; +export * from './icon-pack'; +export * from './icons-library'; diff --git a/src/framework/theme/theme.module.ts b/src/framework/theme/theme.module.ts index 9344925b28..f9cadea3d0 100644 --- a/src/framework/theme/theme.module.ts +++ b/src/framework/theme/theme.module.ts @@ -29,6 +29,7 @@ import { NbLayoutDirectionService, NbLayoutDirection, NB_LAYOUT_DIRECTION } from import { NbLayoutScrollService } from './services/scroll.service'; import { NbLayoutRulerService } from './services/ruler.service'; import { NbOverlayModule } from './components/cdk'; +import { NbIconsLibrary } from './services/icons/icons-library'; export function nbWindowFactory() { return window; @@ -77,6 +78,7 @@ export class NbThemeModule { NbLayoutScrollService, NbLayoutRulerService, ...NbOverlayModule.forRoot().providers, + NbIconsLibrary, ], }; } diff --git a/src/playground/with-layout/icon/icon-showcase.component.html b/src/playground/with-layout/icon/icon-showcase.component.html index 9c83d37ba2..b36a0d2a01 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.html +++ b/src/playground/with-layout/icon/icon-showcase.component.html @@ -1,11 +1,13 @@ + - - - - - + + + + + + diff --git a/src/playground/with-layout/icon/icon-showcase.component.ts b/src/playground/with-layout/icon/icon-showcase.component.ts index f0e3da405f..a34cce2354 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.ts +++ b/src/playground/with-layout/icon/icon-showcase.component.ts @@ -5,6 +5,7 @@ */ import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { NbIconsLibrary } from '@nebular/theme'; @Component({ selector: 'nb-icon-showcase', @@ -12,4 +13,22 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; templateUrl: './icon-showcase.component.html', }) export class IconShowcaseComponent { + + constructor(private iconsLibrary: NbIconsLibrary) { + this.iconsLibrary.registerFontPack('nebular', { packClass: 'nb', iconPrefix: 'nb' }); + + // package release setup + // tests + // on push + // update all icon components + // migration strategy (for nebular icons, and when eva becomes default) + // do examples: + // icon in button + // icon prefix + // 1. specify pack + // 2. specify props + // 3. custom font pack + // 4. custom svg pack + // 5 custom svg icon rendering + } } diff --git a/src/playground/with-layout/icon/icon.module.ts b/src/playground/with-layout/icon/icon.module.ts index b1451af05c..a5922e7852 100644 --- a/src/playground/with-layout/icon/icon.module.ts +++ b/src/playground/with-layout/icon/icon.module.ts @@ -7,6 +7,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NbIconModule, NbButtonModule, NbCardModule } from '@nebular/theme'; +import { NbEvaIconsModule } from '@nebular/eva-icons'; import { IconRoutingModule } from './icon-routing.module'; import { IconShowcaseComponent } from './icon-showcase.component'; @@ -18,6 +19,7 @@ import { IconShowcaseComponent } from './icon-showcase.component'; imports: [ CommonModule, NbIconModule, + NbEvaIconsModule, NbButtonModule, NbCardModule, IconRoutingModule, From 47bd4852b537c30409907da58d50f19890033166 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Tue, 19 Mar 2019 20:15:57 +0300 Subject: [PATCH 04/33] tests: test icons --- .../theme/components/icon/icon.spec.ts | 51 +++++- .../theme/components/input/input.spec.ts | 2 +- .../theme/services/icons/icon-pack.ts | 2 +- .../theme/services/icons/icon.spec.ts | 75 +++++++++ src/framework/theme/services/icons/icon.ts | 18 ++- .../services/icons/icons-library.spec.ts | 151 ++++++++++++++++++ .../icon/icon-showcase.component.ts | 1 - 7 files changed, 289 insertions(+), 11 deletions(-) create mode 100644 src/framework/theme/services/icons/icon.spec.ts create mode 100644 src/framework/theme/services/icons/icons-library.spec.ts diff --git a/src/framework/theme/components/icon/icon.spec.ts b/src/framework/theme/components/icon/icon.spec.ts index de6b8af7e8..8a40a9d4d2 100644 --- a/src/framework/theme/components/icon/icon.spec.ts +++ b/src/framework/theme/components/icon/icon.spec.ts @@ -4,7 +4,56 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -// import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Component, ElementRef, Input, ViewChild } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NbIconModule } from './icon.module'; +import { NbIconsLibrary } from '../../services/icons/icons-library'; + + +@Component({ + template: ` + + `, +}) +class IconTestComponent { + @ViewChild('iconEl', { read: ElementRef }) iconElement; + + @Input() icon; +} describe('Component: NbIcon', () => { + + let iconTestComponent: IconTestComponent; + let fixture: ComponentFixture; + let iconElement: ElementRef; + let iconsLibrary: NbIconsLibrary; + + beforeEach(() => { + + const bed = TestBed.configureTestingModule({ + imports: [ NbIconModule ], + providers: [ NbIconsLibrary ], + declarations: [ IconTestComponent ], + }); + + fixture = bed.createComponent(IconTestComponent); + iconsLibrary = bed.get(NbIconsLibrary); + + iconsLibrary + .registerSvgPack('svg-pack', { home: '' }, { packClass: 'custom-pack' }); + iconsLibrary.setDefaultPack('svg-pack'); + + iconTestComponent = fixture.componentInstance; + iconElement = iconTestComponent.iconElement; + }); + + it('should render icon', () => { + iconTestComponent.icon = 'home'; + fixture.detectChanges(); + const svg = iconElement.nativeElement.querySelector('svg'); + + expect(iconElement.nativeElement.classList.contains('custom-pack')).toBeTruthy(); + expect(svg.innerHTML).toContain(''); + }); }); diff --git a/src/framework/theme/components/input/input.spec.ts b/src/framework/theme/components/input/input.spec.ts index 7c373cc584..68e15d6f18 100644 --- a/src/framework/theme/components/input/input.spec.ts +++ b/src/framework/theme/components/input/input.spec.ts @@ -44,7 +44,7 @@ describe('Directive: NbInput', () => { let inputElement: Element; let textareaElement: Element; - beforeEach(() => {; + beforeEach(() => { fixture = TestBed.configureTestingModule({ imports: [ NbInputModule ], diff --git a/src/framework/theme/services/icons/icon-pack.ts b/src/framework/theme/services/icons/icon-pack.ts index 44193933a2..8c95a5debb 100644 --- a/src/framework/theme/services/icons/icon-pack.ts +++ b/src/framework/theme/services/icons/icon-pack.ts @@ -10,7 +10,7 @@ export enum NbIconPackType { } export interface NbIconPackParams { - packClass: string, + packClass?: string, iconPrefix?: string, [name: string]: any, } diff --git a/src/framework/theme/services/icons/icon.spec.ts b/src/framework/theme/services/icons/icon.spec.ts new file mode 100644 index 0000000000..6266b8db9c --- /dev/null +++ b/src/framework/theme/services/icons/icon.spec.ts @@ -0,0 +1,75 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { NbFontIcon, NbSvgIcon } from './icon'; + + +describe('icon', () => { + let fontIcon: NbFontIcon; + let svgIcon: NbSvgIcon; + + + it(`font icon renders`, () => { + + fontIcon = new NbFontIcon('home', 'custom', { + packClass: 'custom-pack', + iconPrefix: 'cp', + }); + + expect(fontIcon.render()).toEqual('custom'); + }); + + it(`font icon getAttributes return class`, () => { + + fontIcon = new NbFontIcon('home', '', { + packClass: 'custom-pack', + }); + + expect(fontIcon.getAttributes().class).toEqual('home custom-pack'); + }); + + it(`font icon getAttributes return class with prefix`, () => { + + fontIcon = new NbFontIcon('home', '', { + packClass: 'custom-pack', + iconPrefix: 'cp', + }); + + expect(fontIcon.getAttributes().class).toEqual('cp-home custom-pack'); + }); + + it(`font icon getAttributes return class with name only`, () => { + + fontIcon = new NbFontIcon('home', ''); + + expect(fontIcon.getAttributes().class).toEqual('home'); + }); + + it(`svg icon renders`, () => { + + svgIcon = new NbSvgIcon('home', 'content', { + packClass: 'custom-pack', + }); + + expect(svgIcon.render()).toEqual('content'); + }); + + it(`svg icon getAttributes return class`, () => { + + svgIcon = new NbSvgIcon('home', '', { + packClass: 'custom-pack', + }); + + expect(svgIcon.getAttributes().class).toEqual('custom-pack'); + }); + + it(`font icon getAttributes return class with name only`, () => { + + svgIcon = new NbSvgIcon('home', ''); + + expect(svgIcon.getAttributes()).toEqual({}); + }); +}); diff --git a/src/framework/theme/services/icons/icon.ts b/src/framework/theme/services/icons/icon.ts index c505c21261..672be827db 100644 --- a/src/framework/theme/services/icons/icon.ts +++ b/src/framework/theme/services/icons/icon.ts @@ -11,29 +11,33 @@ export interface NbIcon { export class NbFontIcon implements NbIcon { - constructor(protected name, protected content: any, protected params: NbIconPackParams) {} + constructor(protected name, protected content: any, protected params: NbIconPackParams = {}) {} getAttributes(options?: NbIconOptions) { const name = this.params.iconPrefix ? `${this.params.iconPrefix}-${this.name}` : this.name; return { - 'class': `${name} ${this.params.packClass}`, + 'class': this.params.packClass ? `${name} ${this.params.packClass}` : name, }; } render(options?: NbIconOptions): string { - return ''; + return this.content; } } export class NbSvgIcon implements NbIcon { - constructor(protected name, protected content: any, protected params: NbIconPackParams) {} + constructor(protected name, protected content: any, protected params: NbIconPackParams = {}) {} getAttributes(options?: NbIconOptions) { - return { - 'class': `${this.params.packClass}`, - }; + if (this.params.packClass) { + return { + 'class': `${this.params.packClass}`, + }; + + } + return {}; } render(options?: NbIconOptions): string { diff --git a/src/framework/theme/services/icons/icons-library.spec.ts b/src/framework/theme/services/icons/icons-library.spec.ts new file mode 100644 index 0000000000..0031e6dfa6 --- /dev/null +++ b/src/framework/theme/services/icons/icons-library.spec.ts @@ -0,0 +1,151 @@ +import { TestBed } from '@angular/core/testing'; + +import { NbIconsLibrary } from './icons-library'; +import { NbSvgIcon } from './icon'; + + +describe('icons-library', () => { + let iconsLibrary: NbIconsLibrary; + + beforeEach(() => { + TestBed.resetTestingModule(); + const bed = TestBed.configureTestingModule({ + providers: [ + NbIconsLibrary, + ], + }); + iconsLibrary = bed.get(NbIconsLibrary); + }); + + it('should register raw svg icon', () => { + + iconsLibrary.registerSvgPack('super-pack', { home: '', gear: '' }); + iconsLibrary.setDefaultPack('super-pack'); + + const icon = iconsLibrary.getSvgIcon('home'); + + expect(icon.icon.render()).toEqual(''); + expect(icon.name).toEqual('home'); + expect(icon.pack).toEqual('super-pack'); + expect(icon.type).toEqual('svg'); + }); + + it('should register NbSvgIcon svg icon', () => { + + iconsLibrary.registerSvgPack('super-pack', { + home: new NbSvgIcon('home', '', { packClass: 'sp' }), + }); + iconsLibrary.setDefaultPack('super-pack'); + + const icon = iconsLibrary.getSvgIcon('home'); + + expect(icon.icon.render()).toEqual(''); + expect(icon.icon.getAttributes().class).toEqual('sp'); + expect(icon.name).toEqual('home'); + expect(icon.pack).toEqual('super-pack'); + expect(icon.type).toEqual('svg'); + }); + + it('should register custom svg icon', () => { + + class CustomSvgIcon extends NbSvgIcon { + render() { + return 'custom'; + } + } + + iconsLibrary.registerSvgPack('super-pack', { + home: new CustomSvgIcon('home', '', { packClass: 'sp' }), + }); + iconsLibrary.setDefaultPack('super-pack'); + + const icon = iconsLibrary.getSvgIcon('home'); + + expect(icon.icon.render()).toEqual('custom'); + expect(icon.icon.getAttributes().class).toEqual('sp'); + expect(icon.name).toEqual('home'); + expect(icon.pack).toEqual('super-pack'); + expect(icon.type).toEqual('svg'); + }); + + it('should throw for unknown svg icon', () => { + + iconsLibrary.registerSvgPack('super-pack', { home: '', gear: '' }); + iconsLibrary.setDefaultPack('super-pack'); + + + expect(() => iconsLibrary.getSvgIcon('unknown')) + .toThrowError(`Icon 'unknown' is not registered in pack 'super-pack'`); + }); + + it('should throw for unknown pack', () => { + expect(() => iconsLibrary.getSvgIcon('unknown')).toThrowError(`Icon Pack 'undefined' is not registered`); + }); + + it('should throw for wrong pack type', () => { + + iconsLibrary.registerSvgPack('super-pack', { home: '', gear: '' }); + iconsLibrary.registerFontPack('font-pack'); + iconsLibrary.setDefaultPack('font-pack'); + + + expect(() => iconsLibrary.getSvgIcon('unknown')) + .toThrowError(`Pack 'font-pack' is not an SVG Pack and its type is 'font'`); + }); + + it('should throw for wrong pack', () => { + + iconsLibrary.registerSvgPack('super-pack', { home: '', gear: '' }); + iconsLibrary.registerFontPack('font-pack'); + iconsLibrary.setDefaultPack('super-pack'); + + + expect(() => iconsLibrary.getSvgIcon('unknown')) + .toThrowError(`Icon 'unknown' is not registered in pack 'super-pack'`); + }); + + it('should throw for wrong pack when setting default', () => { + + iconsLibrary.registerFontPack('font-pack'); + + expect(() => iconsLibrary.setDefaultPack('super-pack')) + .toThrowError(`Icon Pack 'super-pack' is not registered`); + }); + + it('should register font icon', () => { + + iconsLibrary.registerFontPack('font-pack', { packClass: 'font', iconPrefix: 'fp' }); + iconsLibrary.setDefaultPack('font-pack'); + + const icon = iconsLibrary.getFontIcon('home'); + + expect(icon.icon.render()).toEqual(undefined); + expect(icon.icon.getAttributes().class).toEqual('fp-home font'); + expect(icon.name).toEqual('home'); + expect(icon.pack).toEqual('font-pack'); + expect(icon.type).toEqual('font'); + }); + + + it('should return icon', () => { + + iconsLibrary.registerSvgPack('super-pack', { home: '', gear: '' }); + iconsLibrary.registerFontPack('font-pack', { packClass: 'font', iconPrefix: 'fp' }); + iconsLibrary.setDefaultPack('font-pack'); + + const icon = iconsLibrary.getIcon('home'); + const svgIcon = iconsLibrary.getIcon('home', 'super-pack'); + + expect(icon.icon.render()).toEqual(undefined); + expect(icon.icon.getAttributes().class).toEqual('fp-home font'); + expect(icon.name).toEqual('home'); + expect(icon.pack).toEqual('font-pack'); + expect(icon.type).toEqual('font'); + + expect(svgIcon.icon.render()).toEqual(''); + expect(svgIcon.name).toEqual('home'); + expect(svgIcon.pack).toEqual('super-pack'); + expect(svgIcon.type).toEqual('svg'); + }); + +}); diff --git a/src/playground/with-layout/icon/icon-showcase.component.ts b/src/playground/with-layout/icon/icon-showcase.component.ts index a34cce2354..7a64fc9e7f 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.ts +++ b/src/playground/with-layout/icon/icon-showcase.component.ts @@ -18,7 +18,6 @@ export class IconShowcaseComponent { this.iconsLibrary.registerFontPack('nebular', { packClass: 'nb', iconPrefix: 'nb' }); // package release setup - // tests // on push // update all icon components // migration strategy (for nebular icons, and when eva becomes default) From 4d13be219386810a9960c0f324591abce805f99e Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Wed, 20 Mar 2019 15:56:23 +0300 Subject: [PATCH 05/33] on push --- src/framework/theme/components/icon/icon.component.ts | 5 ++++- src/framework/theme/services/icons/icons-library.spec.ts | 4 ++-- src/framework/theme/services/icons/icons-library.ts | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/framework/theme/components/icon/icon.component.ts b/src/framework/theme/components/icon/icon.component.ts index 453a80b9bc..1148edb80d 100644 --- a/src/framework/theme/components/icon/icon.component.ts +++ b/src/framework/theme/components/icon/icon.component.ts @@ -5,11 +5,13 @@ */ import { + ChangeDetectionStrategy, Component, ElementRef, HostBinding, Input, - OnChanges, OnInit, + OnChanges, + OnInit, Renderer2, SimpleChanges, } from '@angular/core'; @@ -97,6 +99,7 @@ import { NbIconsLibrary } from '../../services/icons'; selector: 'nb-icon', styleUrls: [`./icon.component.scss`], template: '', + changeDetection: ChangeDetectionStrategy.OnPush, }) export class NbIconComponent implements OnChanges, OnInit { diff --git a/src/framework/theme/services/icons/icons-library.spec.ts b/src/framework/theme/services/icons/icons-library.spec.ts index 0031e6dfa6..f5c6318e6f 100644 --- a/src/framework/theme/services/icons/icons-library.spec.ts +++ b/src/framework/theme/services/icons/icons-library.spec.ts @@ -119,7 +119,7 @@ describe('icons-library', () => { const icon = iconsLibrary.getFontIcon('home'); - expect(icon.icon.render()).toEqual(undefined); + expect(icon.icon.render()).toEqual(''); expect(icon.icon.getAttributes().class).toEqual('fp-home font'); expect(icon.name).toEqual('home'); expect(icon.pack).toEqual('font-pack'); @@ -136,7 +136,7 @@ describe('icons-library', () => { const icon = iconsLibrary.getIcon('home'); const svgIcon = iconsLibrary.getIcon('home', 'super-pack'); - expect(icon.icon.render()).toEqual(undefined); + expect(icon.icon.render()).toEqual(''); expect(icon.icon.getAttributes().class).toEqual('fp-home font'); expect(icon.name).toEqual('home'); expect(icon.pack).toEqual('font-pack'); diff --git a/src/framework/theme/services/icons/icons-library.ts b/src/framework/theme/services/icons/icons-library.ts index 928036baa2..f52d5c6cdc 100644 --- a/src/framework/theme/services/icons/icons-library.ts +++ b/src/framework/theme/services/icons/icons-library.ts @@ -89,7 +89,7 @@ export class NbIconsLibrary { name, pack: iconsPack.name, type: NbIconPackType.FONT, - icon: this.createFontIcon(name, icon, iconsPack.params), + icon: this.createFontIcon(name, icon ? icon : '', iconsPack.params), }; } From 1aa14a8822724d70d6fbf17e55dd21a6af8c7e53 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Wed, 20 Mar 2019 17:33:02 +0300 Subject: [PATCH 06/33] feat: enable nebular-icons by default --- DEV_DOCS.md | 2 ++ src/framework/theme/services/theme.service.ts | 6 +++++- src/framework/theme/theme.module.ts | 2 +- src/playground/with-layout/icon/icon-showcase.component.ts | 5 +---- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/DEV_DOCS.md b/DEV_DOCS.md index 49266f2fd7..0c44e2a9c4 100644 --- a/DEV_DOCS.md +++ b/DEV_DOCS.md @@ -331,6 +331,8 @@ To give the user capability switch between live and inline representation of the # Release +0. For major version, search for `@breaking-change` to make sure all breaking changes are covered. + To start a new release (publish the framework packages on NPM) you need: 1. create a new release branch called `release:v1.0.2` diff --git a/src/framework/theme/services/theme.service.ts b/src/framework/theme/services/theme.service.ts index 10fcff1be5..5017607e48 100644 --- a/src/framework/theme/services/theme.service.ts +++ b/src/framework/theme/services/theme.service.ts @@ -13,6 +13,7 @@ import { NB_THEME_OPTIONS } from '../theme.options'; import { NbJSThemeOptions } from './js-themes/theme.options'; import { NbJSThemesRegistry } from './js-themes-registry.service'; import { NbMediaBreakpointsService, NbMediaBreakpoint } from './breakpoints.service'; +import { NbIconsLibrary } from './icons/icons-library'; /** * Main Nebular service. Includes various helper methods. @@ -29,10 +30,13 @@ export class NbThemeService { constructor(@Inject(NB_THEME_OPTIONS) protected options: any, private breakpointService: NbMediaBreakpointsService, - private jsThemesRegistry: NbJSThemesRegistry) { + private jsThemesRegistry: NbJSThemesRegistry, + private iconsLibrary: NbIconsLibrary) { if (options && options.name) { this.changeTheme(options.name); } + // @breaking-change 4.0.0 remove and replace with eva-icons module + this.iconsLibrary.registerFontPack('nebular', { iconPrefix: 'nb' }); } /** diff --git a/src/framework/theme/theme.module.ts b/src/framework/theme/theme.module.ts index f9cadea3d0..5501067332 100644 --- a/src/framework/theme/theme.module.ts +++ b/src/framework/theme/theme.module.ts @@ -70,6 +70,7 @@ export class NbThemeModule { { provide: NB_WINDOW, useFactory: nbWindowFactory }, { provide: NB_DOCUMENT, useExisting: DOCUMENT }, NbJSThemesRegistry, + NbIconsLibrary, NbThemeService, NbMediaBreakpointsService, NbSpinnerService, @@ -78,7 +79,6 @@ export class NbThemeModule { NbLayoutScrollService, NbLayoutRulerService, ...NbOverlayModule.forRoot().providers, - NbIconsLibrary, ], }; } diff --git a/src/playground/with-layout/icon/icon-showcase.component.ts b/src/playground/with-layout/icon/icon-showcase.component.ts index 7a64fc9e7f..fde52a932e 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.ts +++ b/src/playground/with-layout/icon/icon-showcase.component.ts @@ -5,7 +5,6 @@ */ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { NbIconsLibrary } from '@nebular/theme'; @Component({ selector: 'nb-icon-showcase', @@ -14,11 +13,9 @@ import { NbIconsLibrary } from '@nebular/theme'; }) export class IconShowcaseComponent { - constructor(private iconsLibrary: NbIconsLibrary) { - this.iconsLibrary.registerFontPack('nebular', { packClass: 'nb', iconPrefix: 'nb' }); + constructor() { // package release setup - // on push // update all icon components // migration strategy (for nebular icons, and when eva becomes default) // do examples: From ee93e2473fbd32fc87c4739f8b4b3297e06cc742 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Wed, 20 Mar 2019 17:37:09 +0300 Subject: [PATCH 07/33] refactor: remove eva icons --- src/framework/eva-icons/README.md | 1 - src/framework/eva-icons/eva-icons.module.ts | 63 ------------------- src/framework/eva-icons/index.ts | 7 --- src/framework/eva-icons/package.json | 31 --------- src/framework/theme/services/theme.service.ts | 1 + .../icon/icon-showcase.component.html | 10 +-- .../with-layout/icon/icon.module.ts | 2 - 7 files changed, 2 insertions(+), 113 deletions(-) delete mode 100644 src/framework/eva-icons/README.md delete mode 100644 src/framework/eva-icons/eva-icons.module.ts delete mode 100644 src/framework/eva-icons/index.ts delete mode 100644 src/framework/eva-icons/package.json diff --git a/src/framework/eva-icons/README.md b/src/framework/eva-icons/README.md deleted file mode 100644 index 6b7e7c8727..0000000000 --- a/src/framework/eva-icons/README.md +++ /dev/null @@ -1 +0,0 @@ -### @nebular/eva-icons module, more details https://akveo.github.io/nebular/ diff --git a/src/framework/eva-icons/eva-icons.module.ts b/src/framework/eva-icons/eva-icons.module.ts deleted file mode 100644 index d10aa545ac..0000000000 --- a/src/framework/eva-icons/eva-icons.module.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * @license - * Copyright Akveo. All Rights Reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - */ - -import { NgModule } from '@angular/core'; -import { NbIconsLibrary, NbSvgIcon, NbIconPackParams, NbIcons } from '@nebular/theme'; -import { icons } from 'eva-icons'; - -interface NbOriginalEvaIcon { - toSvg(options: NbEvaIconOptions); -} - -export interface NbEvaIconOptions { - width: string, - height: string, - fill: string, - animation: { - type: string, - hover: boolean, - infinite: boolean, - }, -} - -export class NbEvaSvgIcon extends NbSvgIcon { - - constructor(protected name, protected content: NbOriginalEvaIcon, protected params: NbIconPackParams) { - super(name, '', params); - } - - render(options): string { - return this.content.toSvg({ - width: '100%', - height: '100%', - fill: 'currentColor', - ...options, - }); - } -} - -@NgModule({}) -export class NbEvaIconsModule { - - private NAME = 'eva'; - - constructor(iconLibrary: NbIconsLibrary) { - iconLibrary.registerSvgPack(this.NAME, this.createIcons()); - iconLibrary.setDefaultPack(this.NAME); - } - - private createIcons(): NbIcons { - return Object - .entries(icons) - .map(([name, icon]) => { - return [name, new NbEvaSvgIcon(name, icon, {packClass: ''})] as [string, NbSvgIcon]; - }) - .reduce((prev, curr) => { - prev[curr[0]] = curr[1]; - return prev; - }, {}); - } -} diff --git a/src/framework/eva-icons/index.ts b/src/framework/eva-icons/index.ts deleted file mode 100644 index 68fc82358e..0000000000 --- a/src/framework/eva-icons/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * @license - * Copyright Akveo. All Rights Reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - */ - -export * from './eva-icons.module'; diff --git a/src/framework/eva-icons/package.json b/src/framework/eva-icons/package.json deleted file mode 100644 index 252b425019..0000000000 --- a/src/framework/eva-icons/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@nebular/eva-icons", - "version": "3.4.0", - "description": "@nebular/eva-icons", - "main": "./bundles/eva-icons.umd.js", - "module": "./index.js", - "typings": "./index.d.ts", - "author": "akveo", - "license": "MIT", - "repository": { - "type": "git", - "url": "git+https://github.com/akveo/nebular.git" - }, - "bugs": { - "url": "https://github.com/akveo/nebular/issues" - }, - "homepage": "https://github.com/akveo/nebular#readme", - "keywords": [ - "angular", - "typescript", - "ng2-admin", - "ngx-admin", - "theme", - "nebular", - "eva-icons" - ], - "peerDependencies": { - "@nebular/theme": "3.4.0", - "eva-icons": "^1.1.1" - } -} diff --git a/src/framework/theme/services/theme.service.ts b/src/framework/theme/services/theme.service.ts index 5017607e48..cd3f564603 100644 --- a/src/framework/theme/services/theme.service.ts +++ b/src/framework/theme/services/theme.service.ts @@ -37,6 +37,7 @@ export class NbThemeService { } // @breaking-change 4.0.0 remove and replace with eva-icons module this.iconsLibrary.registerFontPack('nebular', { iconPrefix: 'nb' }); + this.iconsLibrary.setDefaultPack('nebular'); } /** diff --git a/src/playground/with-layout/icon/icon-showcase.component.html b/src/playground/with-layout/icon/icon-showcase.component.html index b36a0d2a01..e076af236c 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.html +++ b/src/playground/with-layout/icon/icon-showcase.component.html @@ -1,13 +1,5 @@ - - - - - - - - - + diff --git a/src/playground/with-layout/icon/icon.module.ts b/src/playground/with-layout/icon/icon.module.ts index a5922e7852..b1451af05c 100644 --- a/src/playground/with-layout/icon/icon.module.ts +++ b/src/playground/with-layout/icon/icon.module.ts @@ -7,7 +7,6 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NbIconModule, NbButtonModule, NbCardModule } from '@nebular/theme'; -import { NbEvaIconsModule } from '@nebular/eva-icons'; import { IconRoutingModule } from './icon-routing.module'; import { IconShowcaseComponent } from './icon-showcase.component'; @@ -19,7 +18,6 @@ import { IconShowcaseComponent } from './icon-showcase.component'; imports: [ CommonModule, NbIconModule, - NbEvaIconsModule, NbButtonModule, NbCardModule, IconRoutingModule, From 2e5809a5da12fb81ab3fa2691581a79a211dc9d9 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Thu, 21 Mar 2019 16:40:45 +0300 Subject: [PATCH 08/33] refactor(actions): use nb-icon instead of i --- .../actions/_actions.component.theme.scss | 10 ++-- .../components/actions/actions.component.scss | 6 +-- .../components/actions/actions.component.ts | 6 +-- .../components/actions/actions.module.ts | 2 + .../icon/_icon.component.theme.scss | 2 - .../action/action-badge.component.html | 6 +-- .../action/action-showcase.component.html | 10 ++-- .../action/action-sizes.component.html | 24 ++++----- .../action/action-test.component.ts | 50 +++++++++---------- .../action/action-width.component.html | 4 +- 10 files changed, 59 insertions(+), 61 deletions(-) diff --git a/src/framework/theme/components/actions/_actions.component.theme.scss b/src/framework/theme/components/actions/_actions.component.theme.scss index e5d34588c0..ce441a046e 100644 --- a/src/framework/theme/components/actions/_actions.component.theme.scss +++ b/src/framework/theme/components/actions/_actions.component.theme.scss @@ -26,7 +26,7 @@ } } - i.control-icon { + nb-icon { color: nb-theme(actions-fg); font-size: nb-theme(actions-size-small); } @@ -39,7 +39,7 @@ &.inverse { nb-action { - i.control-icon { + nb-icon { color: nb-theme(actions-bg); } @@ -51,7 +51,7 @@ &.small { nb-action { height: nb-theme(actions-size-small); - i.control-icon { + nb-icon { font-size: nb-theme(actions-size-small); } } @@ -59,7 +59,7 @@ &.medium { nb-action { height: nb-theme(actions-size-medium); - i.control-icon { + nb-icon { font-size: nb-theme(actions-size-medium); } } @@ -67,7 +67,7 @@ &.large { nb-action { height: nb-theme(actions-size-large); - i.control-icon { + nb-icon { font-size: nb-theme(actions-size-large); } } diff --git a/src/framework/theme/components/actions/actions.component.scss b/src/framework/theme/components/actions/actions.component.scss index 34afbf7e0e..a4a401a9ba 100644 --- a/src/framework/theme/components/actions/actions.component.scss +++ b/src/framework/theme/components/actions/actions.component.scss @@ -15,10 +15,8 @@ align-items: center; position: relative; - i.control-icon { - &:hover { - cursor: pointer; - } + nb-icon:hover { + cursor: pointer; } &.disabled { diff --git a/src/framework/theme/components/actions/actions.component.ts b/src/framework/theme/components/actions/actions.component.ts index bbf187c1a7..174aee57cf 100644 --- a/src/framework/theme/components/actions/actions.component.ts +++ b/src/framework/theme/components/actions/actions.component.ts @@ -19,20 +19,20 @@ import { convertToBoolProperty } from '../helpers'; [routerLink]="link" [title]="title" *ngIf="link"> - + - + - + diff --git a/src/framework/theme/components/actions/actions.module.ts b/src/framework/theme/components/actions/actions.module.ts index d8c08654a0..853c9aebe3 100644 --- a/src/framework/theme/components/actions/actions.module.ts +++ b/src/framework/theme/components/actions/actions.module.ts @@ -11,6 +11,7 @@ import { NbSharedModule } from '../shared/shared.module'; import { NbActionComponent, NbActionsComponent } from './actions.component'; import { NbBadgeModule } from '../badge/badge.module'; +import { NbIconModule } from '../icon/icon.module'; const NB_ACTIONS_COMPONENTS = [ NbActionComponent, @@ -21,6 +22,7 @@ const NB_ACTIONS_COMPONENTS = [ imports: [ NbSharedModule, NbBadgeModule, + NbIconModule, ], declarations: [ ...NB_ACTIONS_COMPONENTS, diff --git a/src/framework/theme/components/icon/_icon.component.theme.scss b/src/framework/theme/components/icon/_icon.component.theme.scss index 69810fd104..659f3f3824 100644 --- a/src/framework/theme/components/icon/_icon.component.theme.scss +++ b/src/framework/theme/components/icon/_icon.component.theme.scss @@ -8,8 +8,6 @@ nb-icon { font-size: nb-theme(icon-font-size); line-height: nb-theme(icon-line-height); - width: nb-theme(icon-width); - height: nb-theme(icon-height); &.primary-icon { color: nb-theme(icon-primary-fg); diff --git a/src/playground/with-layout/action/action-badge.component.html b/src/playground/with-layout/action/action-badge.component.html index 8127b23147..0fcb6fa15b 100644 --- a/src/playground/with-layout/action/action-badge.component.html +++ b/src/playground/with-layout/action/action-badge.component.html @@ -2,16 +2,16 @@ - - - diff --git a/src/playground/with-layout/action/action-showcase.component.html b/src/playground/with-layout/action/action-showcase.component.html index 942d486418..7759f656ee 100644 --- a/src/playground/with-layout/action/action-showcase.component.html +++ b/src/playground/with-layout/action/action-showcase.component.html @@ -2,11 +2,11 @@ - - - - - + + + + + Custom Action diff --git a/src/playground/with-layout/action/action-sizes.component.html b/src/playground/with-layout/action/action-sizes.component.html index 75a4baeaa7..40067b6e1d 100644 --- a/src/playground/with-layout/action/action-sizes.component.html +++ b/src/playground/with-layout/action/action-sizes.component.html @@ -2,10 +2,10 @@ - - - - + + + + @@ -15,10 +15,10 @@ - - - - + + + + @@ -28,10 +28,10 @@ - - - - + + + + diff --git a/src/playground/with-layout/action/action-test.component.ts b/src/playground/with-layout/action/action-test.component.ts index d0e4baff68..ad079dca99 100644 --- a/src/playground/with-layout/action/action-test.component.ts +++ b/src/playground/with-layout/action/action-test.component.ts @@ -13,14 +13,14 @@ import { NbBadgeComponent } from '@nebular/theme'; - - + + - - - + + + Hello @@ -31,14 +31,14 @@ import { NbBadgeComponent } from '@nebular/theme'; - - + + - - - + + + Hello @@ -49,14 +49,14 @@ import { NbBadgeComponent } from '@nebular/theme'; - - + + - - - + + + Hello @@ -67,14 +67,14 @@ import { NbBadgeComponent } from '@nebular/theme'; - - + + - - - + + + Hello @@ -95,31 +95,31 @@ import { NbBadgeComponent } from '@nebular/theme'; badgeText="29" [badgeStatus]="badge.STATUS_DANGER" [badgePosition]="badge.TOP_LEFT" - icon="ion-ios-flower-outline"> + icon="email"> + icon="email"> + icon="email"> + icon="email"> Badge diff --git a/src/playground/with-layout/action/action-width.component.html b/src/playground/with-layout/action/action-width.component.html index 70089f5ab4..4aad1ac602 100644 --- a/src/playground/with-layout/action/action-width.component.html +++ b/src/playground/with-layout/action/action-width.component.html @@ -2,8 +2,8 @@ - - + + From 21c02b952785a0c05b51ac30321d79b64aaef767 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Thu, 21 Mar 2019 16:57:22 +0300 Subject: [PATCH 09/33] refactor(theme): remove use of scss functions (#1256) BREAKING CHANGES: - calendar - use primary button in cosmic theme - checkbox - `opacity` instead of `lightning` - context-menu, popover, datepicker - `calc` instead of `round` and scss calculations - input - `opacity` for placeholder instead of `lightning` - tabs - remove gradient for tab bottom separator in cosmic theme - toastr - use `background-color` instead of the gradient in cosmic theme - text colors are now used from success/primary/warning/etc colors - add color palette instead of generating colors using scss-functions, an example for `primary` `color-primary-200` `color-primary-300` `color-primary-400` `color-primary-600` `color-primary-700` `create-colors-palette()` scss function that can be used during the theme installation process to generate palette automatically Closes #1228 --- src/app/playground-components.ts | 11 + .../bootstrap/styles/_default-buttons.scss | 54 ++-- src/framework/bootstrap/styles/_forms.scss | 4 +- .../bootstrap/styles/_hero-buttons.scss | 296 +++--------------- .../components/button/_button-colors.scss | 48 ++- .../components/button/_button-heroes.scss | 265 +++------------- .../calendar-kit/_calendar-kit.theme.scss | 16 - .../checkbox/_checkbox.component.theme.scss | 3 +- .../_context-menu.component.theme.scss | 8 +- ..._datepicker-container.component.theme.scss | 8 +- .../input/_input.directive.theme.scss | 5 +- .../popover/_popover.component.theme.scss | 8 +- .../_route-tabset.component.theme.scss | 5 - .../tabset/_tabset.component.theme.scss | 7 - .../toastr/_toast.component.theme.scss | 10 +- src/framework/theme/styles/_theming.scss | 29 ++ src/framework/theme/styles/core/_mixins.scss | 10 +- .../styles/global/typography/_typography.scss | 95 ++---- .../theme/styles/themes/_corporate.scss | 26 ++ .../theme/styles/themes/_cosmic.scss | 27 +- .../theme/styles/themes/_default.scss | 101 +++++- .../news-post-placeholder.component.scss | 3 +- .../typography/typography-routing.module.ts | 22 ++ .../typography-showcase.component.html | 65 ++++ .../typography-showcase.component.scss | 25 ++ .../typography-showcase.component.ts | 16 + .../typography/typography.module.ts | 21 ++ .../with-layout/with-layout-routing.module.ts | 4 + 28 files changed, 507 insertions(+), 685 deletions(-) create mode 100644 src/playground/with-layout/typography/typography-routing.module.ts create mode 100644 src/playground/with-layout/typography/typography-showcase.component.html create mode 100644 src/playground/with-layout/typography/typography-showcase.component.scss create mode 100644 src/playground/with-layout/typography/typography-showcase.component.ts create mode 100644 src/playground/with-layout/typography/typography.module.ts diff --git a/src/app/playground-components.ts b/src/app/playground-components.ts index 161bdc87f3..d347836d14 100644 --- a/src/app/playground-components.ts +++ b/src/app/playground-components.ts @@ -1619,6 +1619,17 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [ }, ], }, + { + path: 'typography', + children: [ + { + path: 'typography-showcase.component', + link: '/typography/typography-showcase.component', + component: 'TypographyShowcaseComponent', + name: 'Typography Showcase', + }, + ], + }, { path: 'bootstrap', children: [ diff --git a/src/framework/bootstrap/styles/_default-buttons.scss b/src/framework/bootstrap/styles/_default-buttons.scss index 74f12681dd..456f84f1fe 100644 --- a/src/framework/bootstrap/styles/_default-buttons.scss +++ b/src/framework/bootstrap/styles/_default-buttons.scss @@ -98,22 +98,9 @@ } } -@function btn-hover-color($bg, $percentage: 14%) { - @return tint(nb-theme($bg), $percentage); -} - -@function btn-focus-color($bg, $percentage: 14%) { - @return tint(nb-theme($bg), $percentage); -} - -@function btn-active-color($bg, $percentage: 14%) { - @return shade(nb-theme($bg), $percentage); -} - @mixin btn-outline-focus($focus) { &:focus, &.focus { - color: nb-theme(btn-outline-focus-fg); border-color: $focus; box-shadow: none; } @@ -151,90 +138,87 @@ // Focus @mixin btn-primary-focus() { - @include btn-focus(btn-focus-color(btn-primary-bg)); + @include btn-focus(nb-theme(btn-primary-hover-bg)); } @mixin btn-success-focus() { - @include btn-focus(btn-focus-color(btn-success-bg)); + @include btn-focus(nb-theme(btn-success-hover-bg)); } @mixin btn-warning-focus() { - @include btn-focus(btn-focus-color(btn-warning-bg)); + @include btn-focus(nb-theme(btn-warning-hover-bg)); } @mixin btn-info-focus() { - @include btn-focus(btn-focus-color(btn-info-bg)); + @include btn-focus(nb-theme(btn-info-hover-bg)); } @mixin btn-danger-focus() { - @include btn-focus(btn-focus-color(btn-danger-bg)); + @include btn-focus(nb-theme(btn-danger-hover-bg)); } @mixin btn-secondary-focus() { - @include btn-outline-focus(btn-focus-color(btn-secondary-border, 20%)); + @include btn-outline-focus(nb-theme(btn-secondary-hover-bg)); } - // Hover @mixin btn-primary-hover() { - @include btn-hover(btn-hover-color(btn-primary-bg)); + @include btn-hover(nb-theme(btn-primary-hover-bg)); } @mixin btn-success-hover() { - @include btn-hover(btn-hover-color(btn-success-bg)); + @include btn-hover(nb-theme(btn-success-hover-bg)); } @mixin btn-warning-hover() { - @include btn-hover(btn-hover-color(btn-warning-bg)); + @include btn-hover(nb-theme(btn-warning-hover-bg)); } @mixin btn-info-hover() { - @include btn-hover(btn-hover-color(btn-info-bg)); + @include btn-hover(nb-theme(btn-info-hover-bg)); } @mixin btn-danger-hover() { - @include btn-hover(btn-hover-color(btn-danger-bg)); + @include btn-hover(nb-theme(btn-danger-hover-bg)); } @mixin btn-secondary-hover() { - @include btn-hover(btn-hover-color(btn-secondary-border)); + @include btn-hover(nb-theme(btn-secondary-hover-bg)); } - // Active @mixin btn-primary-active() { - @include btn-active(btn-active-color(btn-primary-bg)); + @include btn-active(nb-theme(btn-primary-active-bg)); } @mixin btn-success-active() { - @include btn-active(btn-active-color(btn-success-bg)); + @include btn-active(nb-theme(btn-success-active-bg)); } @mixin btn-warning-active() { - @include btn-active(btn-active-color(btn-warning-bg)); + @include btn-active(nb-theme(btn-warning-active-bg)); } @mixin btn-info-active() { - @include btn-active(btn-active-color(btn-info-bg)); + @include btn-active(nb-theme(btn-info-active-bg)); } @mixin btn-danger-active() { - @include btn-active(btn-active-color(btn-danger-bg)); + @include btn-active(nb-theme(btn-danger-active-bg)); } @mixin btn-secondary-active() { - @include btn-active(btn-active-color(btn-secondary-border)); + @include btn-active(nb-theme(btn-secondary-active-bg)); } - // Disabled @mixin btn-disabled() { &:disabled, &.btn-disabled { opacity: nb-theme(btn-disabled-opacity); + cursor: default; } } - @mixin btn-secondary-border() { border: 2px solid nb-theme(btn-secondary-border); } diff --git a/src/framework/bootstrap/styles/_forms.scss b/src/framework/bootstrap/styles/_forms.scss index c088def245..5f97459120 100644 --- a/src/framework/bootstrap/styles/_forms.scss +++ b/src/framework/bootstrap/styles/_forms.scss @@ -160,7 +160,7 @@ } &:hover { - @include label(lighten(nb-theme(checkbox-checked-border-color), 10%), 1); + @include label(nb-theme(checkbox-checked-border-color), 1); } &:disabled { @@ -216,7 +216,7 @@ } &:hover { - @include label(lighten(nb-theme(checkbox-checked-border-color), 10%), 1); + @include label(nb-theme(checkbox-checked-border-color), 1); } &:disabled { diff --git a/src/framework/bootstrap/styles/_hero-buttons.scss b/src/framework/bootstrap/styles/_hero-buttons.scss index c12213c5b1..b5da89994b 100644 --- a/src/framework/bootstrap/styles/_hero-buttons.scss +++ b/src/framework/bootstrap/styles/_hero-buttons.scss @@ -24,16 +24,11 @@ .btn.btn-hero-danger { @include btn-hero-danger(); } - - .btn.btn-hero-secondary { - @include btn-hero-secondary(); - } } @mixin btn-hero-primary() { @include btn-hero-primary-gradient(); @include btn-hero-primary-bevel-glow-shadow(); - @include btn-hero-border-radius(); @include btn-hero-text(); @include btn-hero-primary-focus(); @include btn-hero-primary-hover(); @@ -47,7 +42,6 @@ @mixin btn-hero-success() { @include btn-hero-success-gradient(); @include btn-hero-success-bevel-glow-shadow(); - @include btn-hero-border-radius(); @include btn-hero-text(); @include btn-hero-success-focus(); @include btn-hero-success-hover(); @@ -61,7 +55,6 @@ @mixin btn-hero-warning() { @include btn-hero-warning-gradient(); @include btn-hero-warning-bevel-glow-shadow(); - @include btn-hero-border-radius(); @include btn-hero-text(); @include btn-hero-warning-focus(); @include btn-hero-warning-hover(); @@ -75,7 +68,6 @@ @mixin btn-hero-info() { @include btn-hero-info-gradient(); @include btn-hero-info-bevel-glow-shadow(); - @include btn-hero-border-radius(); @include btn-hero-text(); @include btn-hero-info-focus(); @include btn-hero-info-hover(); @@ -89,7 +81,6 @@ @mixin btn-hero-danger() { @include btn-hero-danger-gradient(); @include btn-hero-danger-bevel-glow-shadow(); - @include btn-hero-border-radius(); @include btn-hero-text(); @include btn-hero-danger-focus(); @include btn-hero-danger-hover(); @@ -100,176 +91,54 @@ @include btn-hero-danger-pulse(); } -@mixin btn-hero-secondary() { - color: nb-theme(btn-outline-fg); - @include btn-hero-secondary-bg(); - @include btn-hero-secondary-bevel-glow-shadow(); - @include btn-hero-border-radius(); - @include btn-hero-text(); - @include btn-hero-secondary-focus(); - @include btn-hero-secondary-hover(); - @include btn-hero-secondary-active(); - @include btn-hero-secondary-border(); - @include btn-hero-disabled(); - @include btn-hero-secondary-pulse(); -} - -@function btn-hero-gradient-left($color, $degrees: 20deg) { - @return adjust-hue($color, $degrees); -} - -// Functions for box-shadow -@function btn-hero-bevel($color) { - @return nb-theme(btn-hero-bevel-size) shade($color, 14%); -} - -@function btn-hero-glow($hero-glow-size, $color) { - @return nb-theme($hero-glow-size) $color; -} - -// Left colors -@function btn-hero-primary-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-primary-bg), nb-theme(btn-hero-primary-degree)); -} - -@function btn-hero-success-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-success-bg), nb-theme(btn-hero-success-degree)); -} - -@function btn-hero-warning-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-warning-bg), nb-theme(btn-hero-warning-degree)); -} - -@function btn-hero-info-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-info-bg), nb-theme(btn-hero-info-degree)); -} - -@function btn-hero-danger-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-danger-bg), nb-theme(btn-hero-danger-degree)); -} - -@function btn-hero-secondary-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-secondary-border), nb-theme(btn-hero-secondary-degree)); -} - -// Middle colors -@function btn-hero-primary-middle-color() { - @return mix(btn-hero-primary-left-color(), nb-theme(btn-primary-bg)); -} - -@function btn-hero-success-middle-color() { - @return mix(btn-hero-success-left-color(), nb-theme(btn-success-bg)); -} - -@function btn-hero-warning-middle-color() { - @return mix(btn-hero-warning-left-color(), nb-theme(btn-warning-bg)); -} - -@function btn-hero-info-middle-color() { - @return mix(btn-hero-info-left-color(), nb-theme(btn-info-bg)); -} - -@function btn-hero-danger-middle-color() { - @return mix(btn-hero-danger-left-color(), nb-theme(btn-danger-bg)); -} - -@function btn-hero-secondary-middle-color() { - @return mix(btn-hero-secondary-left-color(), nb-theme(btn-secondary-border)); -} - -// light gradients - -@function btn-hero-light-gradient($color-left, $color-right) { - $color-left: tint($color-left, 14%); - $color-right: tint($color-right, 14%); - - @return linear-gradient(to right, $color-left, $color-right); -} - @function btn-hero-primary-light-gradient() { - $color-right: nb-theme(btn-primary-bg); - $color-left: btn-hero-primary-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-primary-left-hover-bg), nb-theme(btn-hero-primary-right-hover-bg)); } @function btn-hero-success-light-gradient() { - $color-right: nb-theme(btn-success-bg); - $color-left: btn-hero-success-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-success-left-hover-bg), nb-theme(btn-hero-success-right-hover-bg)); } @function btn-hero-warning-light-gradient() { - $color-right: nb-theme(btn-warning-bg); - $color-left: btn-hero-warning-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-warning-left-hover-bg), nb-theme(btn-hero-warning-right-hover-bg)); } @function btn-hero-info-light-gradient() { - $color-right: nb-theme(btn-info-bg); - $color-left: btn-hero-info-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-info-left-hover-bg), nb-theme(btn-hero-info-right-hover-bg)); } @function btn-hero-danger-light-gradient() { - $color-right: nb-theme(btn-danger-bg); - $color-left: btn-hero-danger-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); -} - -@function btn-hero-secondary-light-gradient() { - $color-right: nb-theme(btn-secondary-bg); - $color-left: btn-hero-secondary-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); -} - -// dark gradients - -@function btn-hero-dark-gradient($color-left, $color-right) { - $color-left: shade($color-left, 14%); - $color-right: shade($color-right, 14%); - - @return linear-gradient(to right, $color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-danger-left-hover-bg), nb-theme(btn-hero-danger-right-hover-bg)); } @function btn-hero-primary-dark-gradient() { - $color-right: nb-theme(btn-primary-bg); - $color-left: btn-hero-primary-left-color(); - - @return btn-hero-dark-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-primary-left-active-bg), nb-theme(btn-hero-primary-right-active-bg)); } @function btn-hero-success-dark-gradient() { - $color-right: nb-theme(btn-success-bg); - $color-left: btn-hero-success-left-color(); - - @return btn-hero-dark-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-success-left-active-bg), nb-theme(btn-hero-success-right-active-bg)); } @function btn-hero-warning-dark-gradient() { - $color-right: nb-theme(btn-warning-bg); - $color-left: btn-hero-warning-left-color(); - - @return btn-hero-dark-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-warning-left-active-bg), nb-theme(btn-hero-warning-right-active-bg)); } @function btn-hero-info-dark-gradient() { - $color-right: nb-theme(btn-info-bg); - $color-left: btn-hero-info-left-color(); - - @return btn-hero-dark-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-info-left-active-bg), nb-theme(btn-hero-info-right-active-bg)); } @function btn-hero-danger-dark-gradient() { - $color-right: nb-theme(btn-danger-bg); - $color-left: btn-hero-danger-left-color(); - - @return btn-hero-dark-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-danger-left-active-bg), nb-theme(btn-hero-danger-right-active-bg)); } // End functions @@ -300,113 +169,75 @@ border-color: transparent; } } - -@mixin btn-hero-border-radius() { - border-radius: nb-theme(btn-hero-border-radius); -} // End help mixins - // Gradient @mixin btn-hero-primary-gradient() { - $color-right: nb-theme(btn-primary-bg); - $color-left: btn-hero-primary-left-color(); - - @include nb-right-gradient($color-left, $color-right); + @include nb-right-gradient(nb-theme(btn-hero-primary-left-bg), nb-theme(btn-hero-primary-right-bg)); } @mixin btn-hero-success-gradient() { - $color-right: nb-theme(btn-success-bg); - $color-left: btn-hero-success-left-color(); - - @include nb-right-gradient($color-left, $color-right); + @include nb-right-gradient(nb-theme(btn-hero-success-left-bg), nb-theme(btn-hero-success-right-bg)); } @mixin btn-hero-warning-gradient() { - $color-right: nb-theme(btn-warning-bg); - $color-left: btn-hero-warning-left-color(); - - @include nb-right-gradient($color-left, $color-right); + @include nb-right-gradient(nb-theme(btn-hero-warning-left-bg), nb-theme(btn-hero-warning-right-bg)); } @mixin btn-hero-info-gradient() { - $color-right: nb-theme(btn-info-bg); - $color-left: btn-hero-info-left-color(); - - @include nb-right-gradient($color-left, $color-right); + @include nb-right-gradient(nb-theme(btn-hero-info-left-bg), nb-theme(btn-hero-info-right-bg)); } @mixin btn-hero-danger-gradient() { - $color-right: nb-theme(btn-danger-bg); - $color-left: btn-hero-danger-left-color(); - - @include nb-right-gradient($color-left, $color-right); -} - -@mixin btn-hero-secondary-bg() { - background-color: nb-theme(btn-secondary-bg); + @include nb-right-gradient(nb-theme(btn-hero-danger-left-bg), nb-theme(btn-hero-danger-right-bg)); } // Bevel @function btn-hero-primary-bevel() { - @return btn-hero-bevel(btn-hero-primary-middle-color()); + @return nb-theme(btn-hero-bevel-size) nb-theme(btn-hero-primary-bevel-color); } @function btn-hero-success-bevel() { - @return btn-hero-bevel(btn-hero-success-middle-color()); + @return nb-theme(btn-hero-bevel-size) nb-theme(btn-hero-success-bevel-color); } @function btn-hero-warning-bevel() { - @return btn-hero-bevel(btn-hero-warning-middle-color()); + @return nb-theme(btn-hero-bevel-size) nb-theme(btn-hero-warning-bevel-color); } @function btn-hero-info-bevel() { - @return btn-hero-bevel(btn-hero-info-middle-color()); + @return nb-theme(btn-hero-bevel-size) nb-theme(btn-hero-info-bevel-color); } @function btn-hero-danger-bevel() { - @return btn-hero-bevel(btn-hero-danger-middle-color()); -} - -@function btn-hero-secondary-bevel() { - @return btn-hero-bevel(btn-hero-secondary-middle-color()); + @return nb-theme(btn-hero-bevel-size) nb-theme(btn-hero-danger-bevel-color); } - // Glow @function btn-hero-primary-glow() { - @return btn-hero-glow(btn-hero-primary-glow-size, btn-hero-primary-middle-color()); + @return nb-theme(btn-hero-glow-size) nb-theme(btn-hero-primary-glow-color); } @function btn-hero-success-glow() { - @return btn-hero-glow(btn-hero-success-glow-size, btn-hero-success-middle-color()); + @return nb-theme(btn-hero-glow-size) nb-theme(btn-hero-success-glow-color); } @function btn-hero-warning-glow() { - @return btn-hero-glow(btn-hero-warning-glow-size, btn-hero-warning-middle-color()); + @return nb-theme(btn-hero-glow-size) nb-theme(btn-hero-warning-glow-color); } @function btn-hero-info-glow() { - @return btn-hero-glow(btn-hero-info-glow-size, btn-hero-info-middle-color()); + @return nb-theme(btn-hero-glow-size) nb-theme(btn-hero-info-glow-color); } @function btn-hero-danger-glow() { - @return btn-hero-glow(btn-hero-danger-glow-size, btn-hero-danger-middle-color()); -} - -@function btn-hero-secondary-glow() { - @return btn-hero-glow(btn-hero-secondary-glow-size, btn-hero-secondary-middle-color()); + @return nb-theme(btn-hero-glow-size) nb-theme(btn-hero-danger-glow-color); } - // Bevel-glow-shadow @mixin btn-hero-bevel-glow-shadow($bevel, $glow, $shadow) { - $box-shadow: $bevel, $glow; - @if ($shadow != 'none') { - $box-shadow: $box-shadow, $shadow; - } - box-shadow: $box-shadow; + box-shadow: $bevel, $glow, $shadow; } @mixin btn-hero-primary-bevel-glow-shadow() { @@ -449,15 +280,6 @@ @include btn-hero-bevel-glow-shadow($bevel, $glow, $shadow); } -@mixin btn-hero-secondary-bevel-glow-shadow() { - $bevel: btn-hero-secondary-bevel(); - $glow: btn-hero-secondary-glow(); - $shadow: nb-theme(btn-hero-shadow); - - @include btn-hero-bevel-glow-shadow($bevel, $glow, $shadow); -} - - // Border @mixin btn-hero-primary-border() { border: none; @@ -479,15 +301,6 @@ border: none; } -@mixin btn-hero-secondary-border() { - border: 2px solid nb-theme(btn-secondary-border); - - @include nb-for-theme(corporate) { - border: none; - } -} - - // Hover @mixin btn-hero-primary-hover() { @include btn-hero-hover(btn-hero-primary-light-gradient()); @@ -509,13 +322,6 @@ @include btn-hero-hover(btn-hero-danger-light-gradient()); } -@mixin btn-hero-secondary-hover() { - &:hover, - .hover { - background-color: rgba(nb-theme(btn-secondary-border), 0.2); - } -} - // Focus @mixin btn-hero-primary-focus() { @include btn-hero-focus(btn-hero-primary-light-gradient()); @@ -537,15 +343,6 @@ @include btn-hero-focus(btn-hero-danger-light-gradient()); } -@mixin btn-hero-secondary-focus() { - $color: nb-theme(btn-secondary-border); - - &:focus, - .focus { - border-color: tint($color, 14%); - } -} - // Active @mixin btn-hero-primary-active() { @include btn-hero-active(btn-hero-primary-dark-gradient()); @@ -567,21 +364,9 @@ @include btn-hero-active(btn-hero-danger-dark-gradient()); } -@mixin btn-hero-secondary-active() { - $color: nb-theme(btn-secondary-border); - - &:active, - .active { - border-color: shade($color, 14%); - box-shadow: none; - background: none; - } -} - - // Disabled @mixin btn-hero-disabled() { - &:disabled { + &:disabled, &.btn-disabled { opacity: nb-theme(btn-disabled-opacity); box-shadow: none; } @@ -634,18 +419,19 @@ @mixin btn-hero-primary-pulse() { @include btn-pulse(hero-primary, nb-theme(color-primary)); } + @mixin btn-hero-success-pulse() { @include btn-pulse(hero-success, nb-theme(color-success)); } + @mixin btn-hero-danger-pulse() { @include btn-pulse(hero-danger, nb-theme(color-danger)); } + @mixin btn-hero-info-pulse() { @include btn-pulse(hero-info, nb-theme(color-info)); } + @mixin btn-hero-warning-pulse() { @include btn-pulse(hero-warning, nb-theme(color-warning)); } -@mixin btn-hero-secondary-pulse() { - @include btn-pulse(hero-secondary, nb-theme(btn-secondary-border)); -} diff --git a/src/framework/theme/components/button/_button-colors.scss b/src/framework/theme/components/button/_button-colors.scss index dddb77e19b..dd21d8b178 100644 --- a/src/framework/theme/components/button/_button-colors.scss +++ b/src/framework/theme/components/button/_button-colors.scss @@ -97,18 +97,6 @@ } } -@function btn-hover-color($bg, $percentage: 14%) { - @return tint(nb-theme($bg), $percentage); -} - -@function btn-focus-color($bg, $percentage: 14%) { - @return tint(nb-theme($bg), $percentage); -} - -@function btn-active-color($bg, $percentage: 14%) { - @return shade(nb-theme($bg), $percentage); -} - @mixin btn-outline-focus($focus) { &:focus, &.focus { @@ -149,77 +137,77 @@ // Focus @mixin btn-primary-focus() { - @include btn-focus(btn-focus-color(btn-primary-bg)); + @include btn-focus(nb-theme(btn-primary-hover-bg)); } @mixin btn-success-focus() { - @include btn-focus(btn-focus-color(btn-success-bg)); + @include btn-focus(nb-theme(btn-success-hover-bg)); } @mixin btn-warning-focus() { - @include btn-focus(btn-focus-color(btn-warning-bg)); + @include btn-focus(nb-theme(btn-warning-hover-bg)); } @mixin btn-info-focus() { - @include btn-focus(btn-focus-color(btn-info-bg)); + @include btn-focus(nb-theme(btn-info-hover-bg)); } @mixin btn-danger-focus() { - @include btn-focus(btn-focus-color(btn-danger-bg)); + @include btn-focus(nb-theme(btn-danger-hover-bg)); } @mixin btn-secondary-focus() { - @include btn-outline-focus(btn-focus-color(btn-secondary-border, 20%)); + @include btn-outline-focus(nb-theme(btn-secondary-hover-bg)); } // Hover @mixin btn-primary-hover() { - @include btn-hover(btn-hover-color(btn-primary-bg)); + @include btn-hover(nb-theme(btn-primary-hover-bg)); } @mixin btn-success-hover() { - @include btn-hover(btn-hover-color(btn-success-bg)); + @include btn-hover(nb-theme(btn-success-hover-bg)); } @mixin btn-warning-hover() { - @include btn-hover(btn-hover-color(btn-warning-bg)); + @include btn-hover(nb-theme(btn-warning-hover-bg)); } @mixin btn-info-hover() { - @include btn-hover(btn-hover-color(btn-info-bg)); + @include btn-hover(nb-theme(btn-info-hover-bg)); } @mixin btn-danger-hover() { - @include btn-hover(btn-hover-color(btn-danger-bg)); + @include btn-hover(nb-theme(btn-danger-hover-bg)); } @mixin btn-secondary-hover() { - @include btn-hover(btn-hover-color(btn-secondary-border)); + @include btn-hover(nb-theme(btn-secondary-hover-bg)); } // Active @mixin btn-primary-active() { - @include btn-active(btn-active-color(btn-primary-bg)); + @include btn-active(nb-theme(btn-primary-active-bg)); } @mixin btn-success-active() { - @include btn-active(btn-active-color(btn-success-bg)); + @include btn-active(nb-theme(btn-success-active-bg)); } @mixin btn-warning-active() { - @include btn-active(btn-active-color(btn-warning-bg)); + @include btn-active(nb-theme(btn-warning-active-bg)); } @mixin btn-info-active() { - @include btn-active(btn-active-color(btn-info-bg)); + @include btn-active(nb-theme(btn-info-active-bg)); } @mixin btn-danger-active() { - @include btn-active(btn-active-color(btn-danger-bg)); + @include btn-active(nb-theme(btn-danger-active-bg)); } @mixin btn-secondary-active() { - @include btn-active(btn-active-color(btn-secondary-border)); + @include btn-active(nb-theme(btn-secondary-active-bg)); } // Disabled diff --git a/src/framework/theme/components/button/_button-heroes.scss b/src/framework/theme/components/button/_button-heroes.scss index 4e3fb80718..7a57504153 100644 --- a/src/framework/theme/components/button/_button-heroes.scss +++ b/src/framework/theme/components/button/_button-heroes.scss @@ -24,10 +24,6 @@ &.btn-hero.btn-danger { @include btn-hero-danger(); } - - &.btn-hero.btn-secondary { - @include btn-hero-secondary(); - } } @mixin btn-hero-primary() { @@ -95,166 +91,54 @@ @include btn-hero-danger-pulse(); } -@mixin btn-hero-secondary() { - color: nb-theme(btn-outline-fg); - @include btn-hero-secondary-bg(); - @include btn-hero-secondary-bevel-glow-shadow(); - @include btn-hero-text(); - @include btn-hero-secondary-focus(); - @include btn-hero-secondary-hover(); - @include btn-hero-secondary-active(); - @include btn-hero-secondary-border(); - @include btn-hero-disabled(); - @include btn-hero-secondary-pulse(); -} - -@function btn-hero-gradient-left($color, $degrees: 20deg) { - @return adjust-hue($color, $degrees); -} - -// Functions for box-shadow -@function btn-hero-bevel($color) { - @return nb-theme(btn-hero-bevel-size) shade($color, 14%); -} - -@function btn-hero-glow($color) { - @return nb-theme(btn-hero-glow-size) $color; -} - -// Left colors -@function btn-hero-primary-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-primary-bg)); -} - -@function btn-hero-success-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-success-bg)); -} - -@function btn-hero-warning-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-warning-bg), 10deg); -} - -@function btn-hero-info-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-info-bg), -10deg); -} - -@function btn-hero-danger-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-danger-bg), -20deg); -} - -@function btn-hero-secondary-left-color() { - @return btn-hero-gradient-left(nb-theme(btn-secondary-border)); -} - -// Middle colors -@function btn-hero-primary-middle-color() { - @return mix(btn-hero-primary-left-color(), nb-theme(btn-primary-bg)); -} - -@function btn-hero-success-middle-color() { - @return mix(btn-hero-success-left-color(), nb-theme(btn-success-bg)); -} - -@function btn-hero-warning-middle-color() { - @return mix(btn-hero-warning-left-color(), nb-theme(btn-warning-bg)); -} - -@function btn-hero-info-middle-color() { - @return mix(btn-hero-info-left-color(), nb-theme(btn-info-bg)); -} - -@function btn-hero-danger-middle-color() { - @return mix(btn-hero-danger-left-color(), nb-theme(btn-danger-bg)); -} - -@function btn-hero-secondary-middle-color() { - @return mix(btn-hero-secondary-left-color(), nb-theme(btn-secondary-border)); -} - -// light gradients -@function btn-hero-light-gradient($color-left, $color-right) { - $color-left: tint($color-left, 14%); - $color-right: tint($color-right, 14%); - - @return linear-gradient(to right, $color-left, $color-right); -} - @function btn-hero-primary-light-gradient() { - $color-right: nb-theme(btn-primary-bg); - $color-left: btn-hero-primary-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-primary-left-hover-bg), nb-theme(btn-hero-primary-right-hover-bg)); } @function btn-hero-success-light-gradient() { - $color-right: nb-theme(btn-success-bg); - $color-left: btn-hero-success-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-success-left-hover-bg), nb-theme(btn-hero-success-right-hover-bg)); } @function btn-hero-warning-light-gradient() { - $color-right: nb-theme(btn-warning-bg); - $color-left: btn-hero-warning-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-warning-left-hover-bg), nb-theme(btn-hero-warning-right-hover-bg)); } @function btn-hero-info-light-gradient() { - $color-right: nb-theme(btn-info-bg); - $color-left: btn-hero-info-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-info-left-hover-bg), nb-theme(btn-hero-info-right-hover-bg)); } @function btn-hero-danger-light-gradient() { - $color-right: nb-theme(btn-danger-bg); - $color-left: btn-hero-danger-left-color(); - - @return btn-hero-light-gradient($color-left, $color-right); -} - -// dark gradients -@function btn-hero-dark-gradient($color-left, $color-right) { - $color-left: shade($color-left, 14%); - $color-right: shade($color-right, 14%); - - @return linear-gradient(to right, $color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-danger-left-hover-bg), nb-theme(btn-hero-danger-right-hover-bg)); } @function btn-hero-primary-dark-gradient() { - $color-right: nb-theme(btn-primary-bg); - $color-left: btn-hero-primary-left-color(); - - @return btn-hero-dark-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-primary-left-active-bg), nb-theme(btn-hero-primary-right-active-bg)); } @function btn-hero-success-dark-gradient() { - $color-right: nb-theme(btn-success-bg); - $color-left: btn-hero-success-left-color(); - - @return btn-hero-dark-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-success-left-active-bg), nb-theme(btn-hero-success-right-active-bg)); } @function btn-hero-warning-dark-gradient() { - $color-right: nb-theme(btn-warning-bg); - $color-left: btn-hero-warning-left-color(); - - @return btn-hero-dark-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-warning-left-active-bg), nb-theme(btn-hero-warning-right-active-bg)); } @function btn-hero-info-dark-gradient() { - $color-right: nb-theme(btn-info-bg); - $color-left: btn-hero-info-left-color(); - - @return btn-hero-dark-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-info-left-active-bg), nb-theme(btn-hero-info-right-active-bg)); } @function btn-hero-danger-dark-gradient() { - $color-right: nb-theme(btn-danger-bg); - $color-left: btn-hero-danger-left-color(); - - @return btn-hero-dark-gradient($color-left, $color-right); + @return + linear-gradient(to right, nb-theme(btn-hero-danger-left-active-bg), nb-theme(btn-hero-danger-right-active-bg)); } // End functions @@ -289,102 +173,71 @@ // Gradient @mixin btn-hero-primary-gradient() { - $color-right: nb-theme(btn-primary-bg); - $color-left: btn-hero-primary-left-color(); - - @include nb-right-gradient($color-left, $color-right); + @include nb-right-gradient(nb-theme(btn-hero-primary-left-bg), nb-theme(btn-hero-primary-right-bg)); } @mixin btn-hero-success-gradient() { - $color-right: nb-theme(btn-success-bg); - $color-left: btn-hero-success-left-color(); - - @include nb-right-gradient($color-left, $color-right); + @include nb-right-gradient(nb-theme(btn-hero-success-left-bg), nb-theme(btn-hero-success-right-bg)); } @mixin btn-hero-warning-gradient() { - $color-right: nb-theme(btn-warning-bg); - $color-left: btn-hero-warning-left-color(); - - @include nb-right-gradient($color-left, $color-right); + @include nb-right-gradient(nb-theme(btn-hero-warning-left-bg), nb-theme(btn-hero-warning-right-bg)); } @mixin btn-hero-info-gradient() { - $color-right: nb-theme(btn-info-bg); - $color-left: btn-hero-info-left-color(); - - @include nb-right-gradient($color-left, $color-right); + @include nb-right-gradient(nb-theme(btn-hero-info-left-bg), nb-theme(btn-hero-info-right-bg)); } @mixin btn-hero-danger-gradient() { - $color-right: nb-theme(btn-danger-bg); - $color-left: btn-hero-danger-left-color(); - - @include nb-right-gradient($color-left, $color-right); -} - -@mixin btn-hero-secondary-bg() { - background-color: nb-theme(btn-secondary-bg); + @include nb-right-gradient(nb-theme(btn-hero-danger-left-bg), nb-theme(btn-hero-danger-right-bg)); } // Bevel @function btn-hero-primary-bevel() { - @return btn-hero-bevel(btn-hero-primary-middle-color()); + @return nb-theme(btn-hero-bevel-size) nb-theme(btn-hero-primary-bevel-color); } @function btn-hero-success-bevel() { - @return btn-hero-bevel(btn-hero-success-middle-color()); + @return nb-theme(btn-hero-bevel-size) nb-theme(btn-hero-success-bevel-color); } @function btn-hero-warning-bevel() { - @return btn-hero-bevel(btn-hero-warning-middle-color()); + @return nb-theme(btn-hero-bevel-size) nb-theme(btn-hero-warning-bevel-color); } @function btn-hero-info-bevel() { - @return btn-hero-bevel(btn-hero-info-middle-color()); + @return nb-theme(btn-hero-bevel-size) nb-theme(btn-hero-info-bevel-color); } @function btn-hero-danger-bevel() { - @return btn-hero-bevel(btn-hero-danger-middle-color()); -} - -@function btn-hero-secondary-bevel() { - @return btn-hero-bevel(btn-hero-secondary-middle-color()); + @return nb-theme(btn-hero-bevel-size) nb-theme(btn-hero-danger-bevel-color); } // Glow @function btn-hero-primary-glow() { - @return btn-hero-glow(btn-hero-primary-middle-color()); + @return nb-theme(btn-hero-glow-size) nb-theme(btn-hero-primary-glow-color); } @function btn-hero-success-glow() { - @return btn-hero-glow(btn-hero-success-middle-color()); + @return nb-theme(btn-hero-glow-size) nb-theme(btn-hero-success-glow-color); } @function btn-hero-warning-glow() { - @return btn-hero-glow(btn-hero-warning-middle-color()); + @return nb-theme(btn-hero-glow-size) nb-theme(btn-hero-warning-glow-color); } @function btn-hero-info-glow() { - @return btn-hero-glow(btn-hero-info-middle-color()); + @return nb-theme(btn-hero-glow-size) nb-theme(btn-hero-info-glow-color); } @function btn-hero-danger-glow() { - @return btn-hero-glow(btn-hero-danger-middle-color()); -} - -@function btn-hero-secondary-glow() { - @return btn-hero-glow(btn-hero-secondary-middle-color()); + @return nb-theme(btn-hero-glow-size) nb-theme(btn-hero-danger-glow-color); } // Bevel-glow-shadow @mixin btn-hero-bevel-glow-shadow($bevel, $glow, $shadow) { - $box-shadow: $bevel, $glow; - @if ($shadow != 'none') { - $box-shadow: $box-shadow, $shadow; - } - box-shadow: $box-shadow; + box-shadow: $bevel, $glow, $shadow; } @mixin btn-hero-primary-bevel-glow-shadow() { @@ -427,14 +280,6 @@ @include btn-hero-bevel-glow-shadow($bevel, $glow, $shadow); } -@mixin btn-hero-secondary-bevel-glow-shadow() { - $bevel: btn-hero-secondary-bevel(); - $glow: btn-hero-secondary-glow(); - $shadow: nb-theme(btn-hero-shadow); - - @include btn-hero-bevel-glow-shadow($bevel, $glow, $shadow); -} - // Border @mixin btn-hero-primary-border() { border: none; @@ -456,10 +301,6 @@ border: none; } -@mixin btn-hero-secondary-border() { - border: 2px solid nb-theme(btn-secondary-border); -} - // Hover @mixin btn-hero-primary-hover() { @include btn-hero-hover(btn-hero-primary-light-gradient()); @@ -481,13 +322,6 @@ @include btn-hero-hover(btn-hero-danger-light-gradient()); } -@mixin btn-hero-secondary-hover() { - &:hover, - .hover { - background-color: rgba(nb-theme(btn-secondary-border), 0.2); - } -} - // Focus @mixin btn-hero-primary-focus() { @include btn-hero-focus(btn-hero-primary-light-gradient()); @@ -509,15 +343,6 @@ @include btn-hero-focus(btn-hero-danger-light-gradient()); } -@mixin btn-hero-secondary-focus() { - $color: nb-theme(btn-secondary-border); - - &:focus, - .focus { - border-color: tint($color, 14%); - } -} - // Active @mixin btn-hero-primary-active() { @include btn-hero-active(btn-hero-primary-dark-gradient()); @@ -539,17 +364,6 @@ @include btn-hero-active(btn-hero-danger-dark-gradient()); } -@mixin btn-hero-secondary-active() { - $color: nb-theme(btn-secondary-border); - - &:active, - .active { - border-color: shade($color, 14%); - box-shadow: none; - background: none; - } -} - // Disabled @mixin btn-hero-disabled() { &:disabled, &.btn-disabled { @@ -605,18 +419,19 @@ @mixin btn-hero-primary-pulse() { @include btn-pulse(hero-primary, nb-theme(color-primary)); } + @mixin btn-hero-success-pulse() { @include btn-pulse(hero-success, nb-theme(color-success)); } + @mixin btn-hero-danger-pulse() { @include btn-pulse(hero-danger, nb-theme(color-danger)); } + @mixin btn-hero-info-pulse() { @include btn-pulse(hero-info, nb-theme(color-info)); } + @mixin btn-hero-warning-pulse() { @include btn-pulse(hero-warning, nb-theme(color-warning)); } -@mixin btn-hero-secondary-pulse() { - @include btn-pulse(hero-secondary, nb-theme(btn-secondary-border)); -} diff --git a/src/framework/theme/components/calendar-kit/_calendar-kit.theme.scss b/src/framework/theme/components/calendar-kit/_calendar-kit.theme.scss index f21231bbfa..ddcd6d376c 100644 --- a/src/framework/theme/components/calendar-kit/_calendar-kit.theme.scss +++ b/src/framework/theme/components/calendar-kit/_calendar-kit.theme.scss @@ -46,10 +46,6 @@ nb-calendar-navigation button[nbButton] { width: nb-theme(calendar-navigation-button-width); - - @include nb-for-theme(default) { - @include btn-success(); - } } nb-calendar-day-picker .day-cell, @@ -102,10 +98,6 @@ background: nb-theme(calendar-hover-item-bg); color: nb-theme(calendar-selected-fg); font-weight: nb-theme(font-weight-bold); - - @include nb-for-theme(cosmic) { - @include btn-hero-success-gradient(); - } } &:active { @@ -151,10 +143,6 @@ background: nb-theme(calendar-hover-item-bg); color: nb-theme(calendar-selected-fg); font-weight: nb-theme(font-weight-bold); - - @include nb-for-theme(cosmic) { - @include btn-hero-success-gradient(); - } } &:active { @@ -198,10 +186,6 @@ background: nb-theme(calendar-hover-item-bg); color: nb-theme(calendar-selected-fg); font-weight: nb-theme(font-weight-bold); - - @include nb-for-theme(cosmic) { - @include btn-hero-success-gradient(); - } } &.selected { diff --git a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss index ce4d051133..b0139e8cb3 100644 --- a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss +++ b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss @@ -11,7 +11,8 @@ &:hover .customised-control-input:enabled + .customised-control-indicator, .customised-control-input:focus:enabled + .customised-control-indicator { - border-color: lighten($color, 10%); + border-color: $color; + opacity: 0.6; } } diff --git a/src/framework/theme/components/context-menu/_context-menu.component.theme.scss b/src/framework/theme/components/context-menu/_context-menu.component.theme.scss index 15988eba1d..c970e7fb5c 100644 --- a/src/framework/theme/components/context-menu/_context-menu.component.theme.scss +++ b/src/framework/theme/components/context-menu/_context-menu.component.theme.scss @@ -38,24 +38,24 @@ } &.nb-overlay-bottom .arrow { - top: calc(-#{$arrow-size} + 1px); + top: calc(-1 * #{$arrow-size} + 1px); left: calc(50% - #{$arrow-size}); } &.nb-overlay-left .arrow { - right: round(-$arrow-size - $arrow-size / 2 + 2px); + right: calc(-1 * #{$arrow-size} - #{$arrow-size} / 2 + 2px); top: calc(50% - #{$arrow-size / 2}); transform: rotate(90deg); } &.nb-overlay-top .arrow { - bottom: calc(-#{$arrow-size} + 1px); + bottom: calc(-1 * #{$arrow-size} + 1px); left: calc(50% - #{$arrow-size}); transform: rotate(180deg); } &.nb-overlay-right .arrow { - left: round(-$arrow-size - $arrow-size / 2 + 2px); + left: calc(-1 * #{$arrow-size} - #{$arrow-size} / 2 + 2px); top: calc(50% - #{$arrow-size / 2}); transform: rotate(270deg); } diff --git a/src/framework/theme/components/datepicker/_datepicker-container.component.theme.scss b/src/framework/theme/components/datepicker/_datepicker-container.component.theme.scss index 8a8a2d0567..c4effd6773 100644 --- a/src/framework/theme/components/datepicker/_datepicker-container.component.theme.scss +++ b/src/framework/theme/components/datepicker/_datepicker-container.component.theme.scss @@ -38,24 +38,24 @@ } &.nb-overlay-bottom .arrow { - top: calc(-#{$arrow-size} + 1px); + top: calc(-1 * #{$arrow-size} + 1px); left: calc(50% - #{$arrow-size}); } &.nb-overlay-left .arrow { - right: round(-$arrow-size - $arrow-size / 2 + 2px); + right: calc(-1 * #{$arrow-size} - #{$arrow-size} / 2 + 2px); top: calc(50% - #{$arrow-size / 2}); transform: rotate(90deg); } &.nb-overlay-top .arrow { - bottom: calc(-#{$arrow-size} + 1px); + bottom: calc(-1 * #{$arrow-size} + 1px); left: calc(50% - #{$arrow-size}); transform: rotate(180deg); } &.nb-overlay-right .arrow { - left: round(-$arrow-size - $arrow-size / 2 + 2px); + left: calc(-1 * #{$arrow-size} - #{$arrow-size} / 2 + 2px); top: calc(50% - #{$arrow-size / 2}); transform: rotate(270deg); } diff --git a/src/framework/theme/components/input/_input.directive.theme.scss b/src/framework/theme/components/input/_input.directive.theme.scss index e79f5c7f14..d948144638 100644 --- a/src/framework/theme/components/input/_input.directive.theme.scss +++ b/src/framework/theme/components/input/_input.directive.theme.scss @@ -26,8 +26,9 @@ &[disabled] { @include install-placeholder( - rgba(nb-theme(form-control-placeholder-color), 0.5), - nb-theme(form-control-placeholder-font-size) + nb-theme(form-control-placeholder-color), + nb-theme(form-control-placeholder-font-size), + 0.5 ); } diff --git a/src/framework/theme/components/popover/_popover.component.theme.scss b/src/framework/theme/components/popover/_popover.component.theme.scss index 588081920e..2d6a79875e 100644 --- a/src/framework/theme/components/popover/_popover.component.theme.scss +++ b/src/framework/theme/components/popover/_popover.component.theme.scss @@ -37,24 +37,24 @@ } &.nb-overlay-bottom .arrow { - top: calc(-#{$arrow-size} + 1px); + top: calc(-1 * #{$arrow-size} + 1px); left: calc(50% - #{$arrow-size}); } &.nb-overlay-left .arrow { - right: round(-$arrow-size - $arrow-size / 2 + 2px); + right: calc(-1 * #{$arrow-size} - #{$arrow-size} / 2 + 2px); top: calc(50% - #{$arrow-size / 2}); transform: rotate(90deg); } &.nb-overlay-top .arrow { - bottom: calc(-#{$arrow-size} + 1px); + bottom: calc(-1 * #{$arrow-size} + 1px); left: calc(50% - #{$arrow-size}); transform: rotate(180deg); } &.nb-overlay-right .arrow { - left: round(-$arrow-size - $arrow-size / 2 + 2px); + left: calc(-1 * #{$arrow-size} - #{$arrow-size} / 2 + 2px); top: calc(50% - #{$arrow-size / 2}); transform: rotate(270deg); } diff --git a/src/framework/theme/components/route-tabset/_route-tabset.component.theme.scss b/src/framework/theme/components/route-tabset/_route-tabset.component.theme.scss index a320ab07d4..6666f10c5b 100644 --- a/src/framework/theme/components/route-tabset/_route-tabset.component.theme.scss +++ b/src/framework/theme/components/route-tabset/_route-tabset.component.theme.scss @@ -33,11 +33,6 @@ &::before { background: nb-theme(route-tabs-selected); - - @include nb-for-theme(cosmic) { - @include btn-hero-success-gradient(); - box-shadow: 0 0 16px -2px btn-hero-success-middle-color(); - } } } diff --git a/src/framework/theme/components/tabset/_tabset.component.theme.scss b/src/framework/theme/components/tabset/_tabset.component.theme.scss index fa6a9a6f1f..ce3e0a1644 100644 --- a/src/framework/theme/components/tabset/_tabset.component.theme.scss +++ b/src/framework/theme/components/tabset/_tabset.component.theme.scss @@ -33,14 +33,7 @@ } &::before { - $color-right: nb-theme(tabs-selected); - $color-left: adjust-hue( - nb-theme(tabs-selected-second-color), - nb-theme(tabs-selected-degrees)); - background: nb-theme(tabs-selected); - - @include nb-right-gradient($color-left, $color-right); } } diff --git a/src/framework/theme/components/toastr/_toast.component.theme.scss b/src/framework/theme/components/toastr/_toast.component.theme.scss index 9386c29b81..6de3a91837 100644 --- a/src/framework/theme/components/toastr/_toast.component.theme.scss +++ b/src/framework/theme/components/toastr/_toast.component.theme.scss @@ -46,7 +46,7 @@ } @include nb-for-theme(cosmic) { - @include btn-hero-success-gradient(); + background-color: nb-theme(color-success); color: nb-theme(toastr-color-fg); i { @@ -68,7 +68,7 @@ } @include nb-for-theme(cosmic) { - @include btn-hero-info-gradient(); + background-color: nb-theme(color-info); color: nb-theme(toastr-color-fg); i { @@ -90,7 +90,7 @@ } @include nb-for-theme(cosmic) { - @include btn-hero-warning-gradient(); + background-color: nb-theme(color-warning); color: nb-theme(toastr-color-fg); i { @@ -112,7 +112,7 @@ } @include nb-for-theme(cosmic) { - @include btn-hero-primary-gradient(); + background-color: nb-theme(color-primary); color: nb-theme(toastr-color-fg); i { @@ -134,7 +134,7 @@ } @include nb-for-theme(cosmic) { - @include btn-hero-danger-gradient(); + background-color: nb-theme(color-danger); color: nb-theme(toastr-color-fg); i { diff --git a/src/framework/theme/styles/_theming.scss b/src/framework/theme/styles/_theming.scss index 4c6c837384..d14b7e23d3 100644 --- a/src/framework/theme/styles/_theming.scss +++ b/src/framework/theme/styles/_theming.scss @@ -54,6 +54,35 @@ $nb-themes-export: () !global; @return $theme; } +@function create-colors-palette($theme) { + $color-keys: ( + color-primary: 20deg, + color-success: 20deg, + color-info: -10deg, + color-warning: 10deg, + color-danger: -20deg, + ); + + @each $key, $degree in $color-keys { + $color: map-get($theme, $key); + + $color-300: tint($color, 14%); + $color-400: adjust-hue($color, $degree); + $color-200: tint($color-400, 14%); + $color-600: mix($color-400, $color); + $color-700: shade($color, 14%); + $color-800: shade($color-600, 14%); + + $theme: map-set($theme, #{$key}-300, $color-300); + $theme: map-set($theme, #{$key}-200, $color-200); + $theme: map-set($theme, #{$key}-400, $color-400); + $theme: map-set($theme, #{$key}-600, $color-600); + $theme: map-set($theme, #{$key}-700, $color-700); + $theme: map-set($theme, #{$key}-600, $color-800); + } + @return $theme; +} + @function nb-register-theme($theme, $name, $default: null) { $theme-data: (); diff --git a/src/framework/theme/styles/core/_mixins.scss b/src/framework/theme/styles/core/_mixins.scss index 5bc246d5bb..01389ad216 100644 --- a/src/framework/theme/styles/core/_mixins.scss +++ b/src/framework/theme/styles/core/_mixins.scss @@ -100,7 +100,7 @@ } } -@mixin install-placeholder($color, $font-size) { +@mixin install-placeholder($color, $font-size, $opacity: 1) { $placeholder-selectors: ( '::-webkit-input-placeholder' '::-moz-placeholder' @@ -109,12 +109,12 @@ ); &::placeholder { - @include placeholder($color, $font-size); + @include placeholder($color, $font-size, $opacity); } @each $selector in $placeholder-selectors { &#{$selector} { - @include placeholder($color, $font-size); + @include placeholder($color, $font-size, $opacity); } &:focus#{$selector} { @@ -123,10 +123,10 @@ } } -@mixin placeholder($color, $font-size) { +@mixin placeholder($color, $font-size, $opacity) { color: $color; font-size: $font-size; - opacity: 1; + opacity: $opacity; transition: opacity 0.3s ease; text-overflow: ellipsis; } diff --git a/src/framework/theme/styles/global/typography/_typography.scss b/src/framework/theme/styles/global/typography/_typography.scss index e6ae6d2ec2..3ae7fb6798 100644 --- a/src/framework/theme/styles/global/typography/_typography.scss +++ b/src/framework/theme/styles/global/typography/_typography.scss @@ -5,46 +5,6 @@ } } -@function main-to-text-color($color, $count: 15%) { - @return tint($color, $count); -} - -@function text-heading() { - @return nb-theme(color-fg-heading); -} - -@function text-body() { - @return nb-theme(color-fg-text); -} - -@function text-hint() { - @return nb-theme(color-fg); -} - -@function text-primary() { - @return main-to-text-color(nb-theme(color-primary)); -} - -@function text-warning() { - @return main-to-text-color(nb-theme(color-warning)); -} - -@function text-success() { - @return main-to-text-color(nb-theme(color-success)); -} - -@function text-info() { - @return main-to-text-color(nb-theme(color-info)); -} - -@function text-danger() { - @return main-to-text-color(nb-theme(color-danger)); -} - -@function text-white() { - @return nb-theme(color-white); -} - @mixin nb-alert-variant($body-color) { background-color: nb-theme(layout-bg); border: none; @@ -54,9 +14,6 @@ color: $body-color!important; } - hr { - border-top-color: darken($body-color, 10%); - } .alert-link { color: $body-color; text-decoration: none; @@ -100,59 +57,59 @@ } .text-primary { - color: text-primary() !important; + color: nb-theme(color-primary) !important; } .text-warning { - color: text-warning() !important; + color: nb-theme(color-warning) !important; } .text-success { - color: text-success() !important; + color: nb-theme(color-success) !important; } .text-info { - color: text-info() !important; + color: nb-theme(color-info) !important; } .text-danger { - color: text-danger() !important; + color: nb-theme(color-danger) !important; } .text-heading { - color: text-heading() !important; + color: nb-theme(color-fg-heading) !important; } .text-body { - color: text-body() !important; + color: nb-theme(color-fg-text) !important; } .text-hint { - color: text-hint() !important; + color: nb-theme(color-fg) !important; } .text-white { - color: text-white() !important; + color: nb-theme(color-white) !important; } .bg-primary { - background-color: text-primary() !important; + background-color: nb-theme(color-primary) !important; } .bg-warning { - background-color: text-warning() !important; + background-color: nb-theme(color-warning) !important; } .bg-success { - background-color: text-success() !important; + background-color: nb-theme(color-success) !important; } .bg-info { - background-color: text-info() !important; + background-color: nb-theme(color-info) !important; } .bg-danger { - background-color: text-danger() !important; + background-color: nb-theme(color-danger) !important; } .bg-heading { - background-color: text-heading() !important; + background-color: nb-theme(color-fg-heading) !important; } .bg-body { - background-color: text-body() !important; + background-color: nb-theme(color-fg-text) !important; } .bg-hint { - background-color: text-hint() !important; + background-color: nb-theme(color-fg) !important; } .bg-white { - background-color: text-white() !important; + background-color: nb-theme(color-white) !important; } .text-indent { text-indent: 2rem; @@ -184,8 +141,8 @@ mark, .mark { padding: 0.05em; - background-color: text-primary(); - color: text-white(); + background-color: nb-theme(color-primary); + color: nb-theme(color-white); } h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { @@ -216,22 +173,22 @@ } .alert-success { - @include nb-alert-variant(text-success()); + @include nb-alert-variant(nb-theme(color-success)); } .alert-info { - @include nb-alert-variant(text-info()); + @include nb-alert-variant(nb-theme(color-info)); } .alert-warning { - @include nb-alert-variant(text-warning()); + @include nb-alert-variant(nb-theme(color-warning)); } .alert-danger { - @include nb-alert-variant(text-danger()); + @include nb-alert-variant(nb-theme(color-danger)); } .alert-primary { - @include nb-alert-variant(text-primary()); + @include nb-alert-variant(nb-theme(color-primary)); } .alert-hint { - @include nb-alert-variant(text-hint()); + @include nb-alert-variant(nb-theme(color-fg)); } } diff --git a/src/framework/theme/styles/themes/_corporate.scss b/src/framework/theme/styles/themes/_corporate.scss index abdb01b144..a417174d2b 100644 --- a/src/framework/theme/styles/themes/_corporate.scss +++ b/src/framework/theme/styles/themes/_corporate.scss @@ -31,6 +31,32 @@ $theme: ( color-warning: #ffa36b, color-danger: #ff6b83, + color-primary-200: #8787ff, + color-primary-300: #87aeff, + color-primary-400: #7473ff, + color-primary-600: #6377db, + color-primary-700: #638adb, + color-success-200: #74afe7, + color-success-300: #74d6e7, + color-success-400: #5da2e3, + color-success-600: #509fc3, + color-success-700: #50b2c3, + color-info-200: #b491ef, + color-info-300: #c491ef, + color-info-400: #a87fec, + color-info-600: #986dcb, + color-info-700: #a06dcb, + color-warning-200: #ffc580, + color-warning-300: #ffb080, + color-warning-400: #ffbc6b, + color-warning-600: #db975c, + color-warning-700: #db8c5c, + color-danger-200: #ff80bf, + color-danger-300: #ff8094, + color-danger-400: #ff6bb4, + color-danger-600: #db5c86, + color-danger-700: #db5c71, + btn-secondary-bg: #edf2f5, btn-secondary-border: #edf2f5, diff --git a/src/framework/theme/styles/themes/_cosmic.scss b/src/framework/theme/styles/themes/_cosmic.scss index 8c8a664039..bcc190f6f4 100644 --- a/src/framework/theme/styles/themes/_cosmic.scss +++ b/src/framework/theme/styles/themes/_cosmic.scss @@ -30,6 +30,32 @@ $theme: ( color-warning: #ffa100, color-danger: #ff386a, + color-primary-200: #b970ff, + color-primary-300: #8970ff, + color-primary-400: #ad59ff, + color-primary-600: #7e4ddb, + color-primary-700: #654ddb, + color-success-200: #24dec8, + color-success-300: #24de8a, + color-success-400: #00d9bf, + color-success-600: #00bb85, + color-success-700: #00bb66, + color-info-200: #24bdff, + color-info-300: #2499ff, + color-info-400: #00b3ff, + color-info-600: #0087db, + color-info-700: #0075db, + color-warning-200: #ffd324, + color-warning-300: #ffae24, + color-warning-400: #ffcc00, + color-warning-600: #db9d00, + color-warning-700: #db8a00, + color-danger-200: #ff54b8, + color-danger-300: #ff547f, + color-danger-400: #ff38ac, + color-danger-600: #db3078, + color-danger-700: #db305b, + link-color: #00f9a6, link-color-hover: #14ffbe, @@ -163,7 +189,6 @@ $theme: ( toastr-color-fg: color-white, toastr-padding: 1.25rem, - toastr-border: 0, toastr-default-background: #bcc3cc, tooltip-fg: color-bg, diff --git a/src/framework/theme/styles/themes/_default.scss b/src/framework/theme/styles/themes/_default.scss index 2fe6c8636c..0b83928abd 100644 --- a/src/framework/theme/styles/themes/_default.scss +++ b/src/framework/theme/styles/themes/_default.scss @@ -52,6 +52,32 @@ $theme: ( color-warning: #ffa100, color-danger: #ff4c6a, + color-primary-200: #bf91ff, + color-primary-300: #9a91ff, + color-primary-400: #b57fff, + color-primary-600: #896ddb, + color-primary-700: #776ddb, + color-success-200: #5be1bd, + color-success-300: #5be190, + color-success-400: #40dcb2, + color-success-600: #37bd83, + color-success-700: #37bd6c, + color-info-200: #65ccff, + color-info-300: #65b2ff, + color-info-400: #4cc4ff, + color-info-600: #419cdb, + color-info-700: #418fdb, + color-warning-200: #ffd324, + color-warning-300: #ffae24, + color-warning-400: #ffcc00, + color-warning-600: #db9d00, + color-warning-700: #db8a00, + color-danger-200: #ff65b2, + color-danger-300: #ff657f, + color-danger-400: #ff4ca6, + color-danger-600: #db4175, + color-danger-700: #db415b, + // TODO: move to constants social-color-facebook: #3b5998, social-color-twitter: #55acee, @@ -320,11 +346,23 @@ $theme: ( btn-cursor: default, btn-primary-bg: color-primary, + btn-primary-hover-bg: color-primary-300, + btn-primary-active-bg: color-primary-600, btn-secondary-bg: transparent, + btn-secondary-hover-bg: #dadfe6, + btn-secondary-active-bg: #dadfe6, btn-info-bg: color-info, + btn-info-hover-bg: color-info-300, + btn-info-active-bg: color-info-600, btn-success-bg: color-success, + btn-success-hover-bg: color-success-300, + btn-success-active-bg: color-success-600, btn-warning-bg: color-warning, + btn-warning-hover-bg: color-warning-300, + btn-warning-active-bg: color-warning-600, btn-danger-bg: color-danger, + btn-danger-hover-bg: color-danger-300, + btn-danger-active-bg: color-danger-600, btn-secondary-border: #dadfe6, btn-secondary-border-width: 2px, @@ -351,23 +389,58 @@ $theme: ( btn-semi-round-border-radius: 0.75rem, btn-round-border-radius: 1.5rem, - btn-hero-shadow: none, + btn-hero-shadow: 0 0 transparent, btn-hero-text-shadow: none, btn-hero-bevel-size: 0 0 0 0, btn-hero-glow-size: 0 0 0 0, - btn-hero-primary-glow-size: btn-hero-glow-size, - btn-hero-success-glow-size: btn-hero-glow-size, - btn-hero-warning-glow-size: btn-hero-glow-size, - btn-hero-info-glow-size: btn-hero-glow-size, - btn-hero-danger-glow-size: btn-hero-glow-size, - btn-hero-secondary-glow-size: btn-hero-glow-size, - btn-hero-degree: 20deg, - btn-hero-primary-degree: btn-hero-degree, - btn-hero-success-degree: btn-hero-degree, - btn-hero-warning-degree: 10deg, - btn-hero-info-degree: -10deg, - btn-hero-danger-degree: -20deg, - btn-hero-secondary-degree: btn-hero-degree, + + btn-hero-primary-bevel-color: color-primary-600, + btn-hero-success-bevel-color: color-success-600, + btn-hero-warning-bevel-color: color-warning-600, + btn-hero-info-bevel-color: color-info-600, + btn-hero-danger-bevel-color: color-danger-600, + btn-hero-secondary-bevel-color: color-secondary-600, + + btn-hero-primary-glow-color: color-primary-700, + btn-hero-success-glow-color: color-success-700, + btn-hero-warning-glow-color: color-warning-700, + btn-hero-info-glow-color: color-info-700, + btn-hero-danger-glow-color: color-danger-700, + btn-hero-secondary-glow-color: color-secondary-700, + + btn-hero-primary-left-bg: color-primary-400, + btn-hero-primary-right-bg: color-primary, + btn-hero-info-left-bg: color-info-400, + btn-hero-info-right-bg: color-info, + btn-hero-success-left-bg: color-success-400, + btn-hero-success-right-bg: color-success, + btn-hero-warning-left-bg: color-warning-400, + btn-hero-warning-right-bg: color-warning, + btn-hero-danger-left-bg: color-danger-400, + btn-hero-danger-right-bg: color-danger, + + btn-hero-primary-left-hover-bg: color-primary-200, + btn-hero-primary-right-hover-bg: color-primary-300, + btn-hero-info-left-hover-bg: color-info-200, + btn-hero-info-right-hover-bg: color-info-300, + btn-hero-success-left-hover-bg: color-success-200, + btn-hero-success-right-hover-bg: color-success-300, + btn-hero-warning-left-hover-bg: color-warning-200, + btn-hero-warning-right-hover-bg: color-warning-300, + btn-hero-danger-left-hover-bg: color-danger-200, + btn-hero-danger-right-hover-bg: color-danger-300, + + btn-hero-primary-left-active-bg: color-primary-400, + btn-hero-primary-right-active-bg: color-primary-600, + btn-hero-info-left-active-bg: color-info-400, + btn-hero-info-right-active-bg: color-info-600, + btn-hero-success-left-active-bg: color-success-400, + btn-hero-success-right-active-bg: color-success-600, + btn-hero-warning-left-active-bg: color-warning-400, + btn-hero-warning-right-active-bg: color-warning-600, + btn-hero-danger-left-active-bg: color-danger-400, + btn-hero-danger-right-active-bg: color-danger-600, + btn-hero-border-radius: radius, btn-outline-fg: color-fg-heading, diff --git a/src/playground/with-layout/infinite-list/news-post-placeholder.component.scss b/src/playground/with-layout/infinite-list/news-post-placeholder.component.scss index 525ea39e7f..2e9553643a 100644 --- a/src/playground/with-layout/infinite-list/news-post-placeholder.component.scss +++ b/src/playground/with-layout/infinite-list/news-post-placeholder.component.scss @@ -20,6 +20,7 @@ @include nb-install-component() { [class$='placeholder'] { - background: rgba(nb-theme(layout-bg), 0.6); + background: nb-theme(layout-bg); + opacity: 0.6; } } diff --git a/src/playground/with-layout/typography/typography-routing.module.ts b/src/playground/with-layout/typography/typography-routing.module.ts new file mode 100644 index 0000000000..ce19a3ece9 --- /dev/null +++ b/src/playground/with-layout/typography/typography-routing.module.ts @@ -0,0 +1,22 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { NgModule } from '@angular/core'; +import { RouterModule, Route} from '@angular/router'; +import { TypographyShowcaseComponent } from './typography-showcase.component'; + +const routes: Route[] = [ + { + path: 'typography-showcase.component', + component: TypographyShowcaseComponent, + }, +]; + +@NgModule({ + imports: [ RouterModule.forChild(routes) ], + exports: [ RouterModule ], +}) +export class TypographyRoutingModule {} diff --git a/src/playground/with-layout/typography/typography-showcase.component.html b/src/playground/with-layout/typography/typography-showcase.component.html new file mode 100644 index 0000000000..7a1ae47b27 --- /dev/null +++ b/src/playground/with-layout/typography/typography-showcase.component.html @@ -0,0 +1,65 @@ + + + Font Colors + + +
+
+
+
+
Heading Text
+ Far far away, behind the your awesomeness. +
+
+
+
+
+
Body Text
+ Far far away, behind the your awesomeness. +
+
+
+
+
+
Hint Text
+ Far far away, behind the your awesomeness. +
+
+
+
+
+
Primary Text
+ Far far away, behind the your awesomeness. +
+
+
+
+
+
Success Text
+ Far far away, behind the your awesomeness. +
+
+
+
+
+
Info Text
+ Far far away, behind the your awesomeness. +
+
+
+
+
+
Warning Text
+ Far far away, behind the your awesomeness. +
+
+
+
+
+
Danger Text
+ Far far away, behind the your awesomeness. +
+
+
+
+
diff --git a/src/playground/with-layout/typography/typography-showcase.component.scss b/src/playground/with-layout/typography/typography-showcase.component.scss new file mode 100644 index 0000000000..7d90943e8b --- /dev/null +++ b/src/playground/with-layout/typography/typography-showcase.component.scss @@ -0,0 +1,25 @@ +.colors { + display: flex; + flex-direction: column; + + .item { + display: flex; + align-items: center; + margin-bottom: 1.25rem; + &:last-child { + margin-bottom: 0; + } + } + + .color { + width: 86px; + height: 60px; + border-top-right-radius: 1rem; + border-bottom-left-radius: 1rem; + margin-right: 1rem; + } + + h1, h2, h3, h4, h5, h6 { + margin-bottom: 0.25rem; + } +} diff --git a/src/playground/with-layout/typography/typography-showcase.component.ts b/src/playground/with-layout/typography/typography-showcase.component.ts new file mode 100644 index 0000000000..4e3cfb916f --- /dev/null +++ b/src/playground/with-layout/typography/typography-showcase.component.ts @@ -0,0 +1,16 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + selector: 'nb-typography-showcase', + styleUrls: ['./typography-showcase.component.scss'], + templateUrl: './typography-showcase.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TypographyShowcaseComponent { +} diff --git a/src/playground/with-layout/typography/typography.module.ts b/src/playground/with-layout/typography/typography.module.ts new file mode 100644 index 0000000000..80ae9dba46 --- /dev/null +++ b/src/playground/with-layout/typography/typography.module.ts @@ -0,0 +1,21 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { NgModule } from '@angular/core'; +import { TypographyRoutingModule } from './typography-routing.module'; +import { TypographyShowcaseComponent } from './typography-showcase.component'; +import { NbCardModule } from '@nebular/theme'; + +@NgModule({ + declarations: [ + TypographyShowcaseComponent, + ], + imports: [ + NbCardModule, + TypographyRoutingModule, + ], +}) +export class TypographyModule {} diff --git a/src/playground/with-layout/with-layout-routing.module.ts b/src/playground/with-layout/with-layout-routing.module.ts index 71edc66665..e5ececd830 100644 --- a/src/playground/with-layout/with-layout-routing.module.ts +++ b/src/playground/with-layout/with-layout-routing.module.ts @@ -153,6 +153,10 @@ const routes: Route[] = [ path: 'tree-grid', loadChildren: './tree-grid/tree-grid.module#TreeGridModule', }, + { + path: 'typography', + loadChildren: './typography/typography.module#TypographyModule', + }, ], }, ]; From 74654d2ec46e378d9242d34a467bd278510dc406 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Thu, 21 Mar 2019 18:32:20 +0300 Subject: [PATCH 10/33] feat(theme): css variables support (#1257) Closes #46 --- src/app/playground-components.ts | 22 +++--- .../bootstrap/styles/_button-group.scss | 30 ++++---- .../bootstrap/styles/_dropdowns.scss | 9 +-- src/framework/theme/styles/_theming.scss | 75 +++++++++++++++---- .../typography-showcase.component.html | 2 +- 5 files changed, 89 insertions(+), 49 deletions(-) diff --git a/src/app/playground-components.ts b/src/app/playground-components.ts index d347836d14..793d5594c3 100644 --- a/src/app/playground-components.ts +++ b/src/app/playground-components.ts @@ -1309,6 +1309,17 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [ }, ], }, + { + path: 'typography', + children: [ + { + path: 'typography-showcase.component', + link: '/typography/typography-showcase.component', + component: 'TypographyShowcaseComponent', + name: 'Typography Showcase', + }, + ], + }, { path: 'context-menu', children: [ @@ -1619,17 +1630,6 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [ }, ], }, - { - path: 'typography', - children: [ - { - path: 'typography-showcase.component', - link: '/typography/typography-showcase.component', - component: 'TypographyShowcaseComponent', - name: 'Typography Showcase', - }, - ], - }, { path: 'bootstrap', children: [ diff --git a/src/framework/bootstrap/styles/_button-group.scss b/src/framework/bootstrap/styles/_button-group.scss index e0a3285eab..4764d8e1ae 100644 --- a/src/framework/bootstrap/styles/_button-group.scss +++ b/src/framework/bootstrap/styles/_button-group.scss @@ -6,61 +6,57 @@ @import 'default-buttons'; -@mixin btn-group-separator($color) { - background-color: shade($color, 20%); -} - @mixin btn-group-primary-separator() { - @include btn-group-separator(nb-theme(color-primary)); + @include nb-theme(color-primary-600); } @mixin btn-group-success-separator() { - @include btn-group-separator(nb-theme(color-success)); + @include nb-theme(color-success-600); } @mixin btn-group-warning-separator() { - @include btn-group-separator(nb-theme(color-warning)); + @include nb-theme(color-warning-600); } @mixin btn-group-info-separator() { - @include btn-group-separator(nb-theme(color-info)); + @include nb-theme(color-info-600); } @mixin btn-group-danger-separator() { - @include btn-group-separator(nb-theme(color-danger)); + @include nb-theme(color-danger-600); } @mixin btn-group-secondary-separator() { - @include btn-group-separator(nb-theme(color-primary)); + @include nb-theme(color-primary-600); } @mixin dropdown-separator($color) { - border-left: 1px solid shade($color, 14%); + border-left: 1px solid $color; } @mixin dropdown-primary-separator() { - @include dropdown-separator(nb-theme(btn-primary-bg)); + @include dropdown-separator(nb-theme(btn-primary-active-bg)); } @mixin dropdown-success-separator() { - @include dropdown-separator(nb-theme(btn-success-bg)); + @include dropdown-separator(nb-theme(btn-success-active-bg)); } @mixin dropdown-warning-separator() { - @include dropdown-separator(nb-theme(btn-warning-bg)); + @include dropdown-separator(nb-theme(btn-warning-active-bg)); } @mixin dropdown-info-separator() { - @include dropdown-separator(nb-theme(btn-info-bg)); + @include dropdown-separator(nb-theme(btn-info-active-bg)); } @mixin dropdown-danger-separator() { - @include dropdown-separator(nb-theme(btn-danger-bg)); + @include dropdown-separator(nb-theme(btn-danger-active-bg)); } @mixin dropdown-secondary-separator() { - @include dropdown-separator(nb-theme(btn-secondary-bg)); + @include dropdown-separator(nb-theme(btn-secondary-active-bg)); } diff --git a/src/framework/bootstrap/styles/_dropdowns.scss b/src/framework/bootstrap/styles/_dropdowns.scss index 68d6761ef5..e03d909869 100644 --- a/src/framework/bootstrap/styles/_dropdowns.scss +++ b/src/framework/bootstrap/styles/_dropdowns.scss @@ -34,13 +34,8 @@ @include dropdown-menu-background(nb-theme(btn-secondary-border)); } - -@function dropdown-divider($color) { - @return shade($color, 14%); -} - @mixin dropdown-menu-border($color) { - border-top: 1px solid dropdown-divider($color); + border-top: 1px solid $color; } @mixin dropdown-menu-primary-border() { @@ -69,7 +64,7 @@ @mixin dropdown-menu-divider($color) { - background-color: dropdown-divider($color); + background-color: $color; } @mixin dropdown-menu-primary-divider() { diff --git a/src/framework/theme/styles/_theming.scss b/src/framework/theme/styles/_theming.scss index d14b7e23d3..e8e3f15fcc 100644 --- a/src/framework/theme/styles/_theming.scss +++ b/src/framework/theme/styles/_theming.scss @@ -13,7 +13,7 @@ @import 'core/functions'; $nb-enabled-themes: () !global; -$nb-enable-css-variables: false !global; +$nb-enable-css-custom-properties: false !global !default; $nb-themes: () !global; $nb-themes-non-processed: () !global; @@ -28,28 +28,31 @@ $nb-themes-export: () !global; $tmp: map-get($theme, $value); @if ($tmp != null) { - @return nb-get-value($theme, $value, $tmp); + @if ($nb-enable-css-custom-properties) { + @return var(--#{$value}); + } @else { + @return nb-get-value($theme, $value, $tmp); + } } } @return map-get($theme, $key); } -@function convert-to-css-variables($variables) { +@function convert-to-css-custom-properties($variables) { $result: (); @each $var, $value in $variables { - $result: map-set($result, $var, '--var(#{$var})'); + $result: map-set($result, $var, unquote('var(--#{$var})')); } - @debug $result; @return $result; } @function set-global-theme-vars($theme, $theme-name) { $theme: $theme !global; $theme-name: $theme-name !global; - @if ($nb-enable-css-variables) { - $theme: convert-to-css-variables($theme) !global; + @if ($nb-enable-css-custom-properties) { + $theme: convert-to-css-custom-properties($theme) !global; } @return $theme; } @@ -130,14 +133,19 @@ $nb-themes-export: () !global; @mixin install-css-variables($theme-name, $variables) { .nb-theme-#{$theme-name} { @each $var, $value in $variables { - --#{$var}: $value; + --#{$var}: #{$value}; } } } -// TODO: we hide :host inside of it which is not obvious -@mixin nb-install-component() { +@mixin nb-install-component-with-css-props() { + @warn '`nb-install-component` is unnecessary with css-variables. Deprecated and will be removed as of 5.0.0'; + :host { + @content; + } +} +@mixin nb-install-component-with-scss-vars() { $themes-to-install: get-enabled-themes(); @each $theme-name, $theme in $themes-to-install { @@ -168,12 +176,29 @@ $nb-themes-export: () !global; } } +// TODO: we hide :host inside of it which is not obvious +@mixin nb-install-component() { + + @if ($nb-enable-css-custom-properties) { + + @include nb-install-component-with-css-props() { + @content; + } + + } @else { + + @include nb-install-component-with-scss-vars() { + @content; + } + } +} + @mixin nb-for-theme($name) { @if ($theme-name == $name) { @content; } } - + // Add content for theme into a list of themes @mixin nb-for-themes($names...) { @each $name in $names { @@ -200,14 +225,26 @@ $nb-themes-export: () !global; // TODO: another mixing for the almost same thing @mixin nb-install-root-component() { - @warn '`nb-install-root-component` is depricated, replace with `nb-install-component`, as `body` is root element now'; + @warn '`nb-install-root-component` is deprecated, replace with `nb-install-component`, as `body` is root element now'; @include nb-install-component() { @content; } } -@mixin nb-install-global() { +@mixin nb-install-global-with-css-props() { + $themes-to-install: get-enabled-themes(); + + $theme: map-get($themes-to-install, 'default'); + $theme: set-global-theme-vars($theme, 'default'); + @content; + + @each $theme-name, $theme in $themes-to-install { + @include install-css-variables($theme-name, $theme); + } +} + +@mixin nb-install-global-with-scss-vars() { $themes-to-install: get-enabled-themes(); @each $theme-name, $theme in $themes-to-install { @@ -217,3 +254,15 @@ $nb-themes-export: () !global; } } } + +@mixin nb-install-global() { + @if ($nb-enable-css-custom-properties) { + @include nb-install-global-with-css-props() { + @content; + } + } @else { + @include nb-install-global-with-scss-vars() { + @content; + } + } +} diff --git a/src/playground/with-layout/typography/typography-showcase.component.html b/src/playground/with-layout/typography/typography-showcase.component.html index 7a1ae47b27..c1845c09be 100644 --- a/src/playground/with-layout/typography/typography-showcase.component.html +++ b/src/playground/with-layout/typography/typography-showcase.component.html @@ -1,4 +1,4 @@ - + Font Colors From f840d7a45a5f5c1481283eac87442edf6cafb00b Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Thu, 21 Mar 2019 19:17:59 +0300 Subject: [PATCH 11/33] refactor(chat): use nb-icon instead of span --- .../theme/components/chat/_chat.component.theme.scss | 4 ++++ .../theme/components/chat/chat-form.component.ts | 8 +++++--- .../theme/components/chat/chat-message-file.component.ts | 4 ++-- .../theme/components/chat/chat-message-map.component.ts | 2 +- src/framework/theme/components/chat/chat.module.ts | 2 ++ src/framework/theme/components/icon/icon.component.ts | 5 ++++- src/playground/with-layout/chat/bot-replies.ts | 8 ++++---- .../chat/chat-conversation-showcase.component.ts | 2 +- src/playground/with-layout/chat/chat-drop.component.ts | 2 +- .../chat/chat-message-types-showcase.component.ts | 4 ++-- .../with-layout/chat/chat-showcase.component.ts | 2 +- src/playground/with-layout/chat/messages.ts | 2 +- 12 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/framework/theme/components/chat/_chat.component.theme.scss b/src/framework/theme/components/chat/_chat.component.theme.scss index 99b305b5ab..cd24556c4f 100644 --- a/src/framework/theme/components/chat/_chat.component.theme.scss +++ b/src/framework/theme/components/chat/_chat.component.theme.scss @@ -12,6 +12,10 @@ border-radius: nb-theme(chat-border-radius); box-shadow: nb-theme(chat-shadow); + nb-icon { + font-size: inherit; + } + .header { color: nb-theme(chat-fg-text); padding: nb-theme(chat-padding); diff --git a/src/framework/theme/components/chat/chat-form.component.ts b/src/framework/theme/components/chat/chat-form.component.ts index 1399b240e2..1bd2fa850a 100644 --- a/src/framework/theme/components/chat/chat-form.component.ts +++ b/src/framework/theme/components/chat/chat-form.component.ts @@ -60,7 +60,9 @@ import { DomSanitizer } from '@angular/platform-browser';
×
-
+ +
+ ×
@@ -72,7 +74,7 @@ import { DomSanitizer } from '@angular/platform-browser'; placeholder="{{ fileOver ? 'Drop file to send' : 'Type a message' }}" (keyup.enter)="sendMessage()">
`, @@ -99,7 +101,7 @@ export class NbChatFormComponent { * Send button icon, shown if `buttonTitle` is empty * @type {string} */ - @Input() buttonIcon: string = 'nb-paper-plane'; + @Input() buttonIcon: string = 'paper-plane'; /** * Show send button diff --git a/src/framework/theme/components/chat/chat-message-file.component.ts b/src/framework/theme/components/chat/chat-message-file.component.ts index 6d8cdd1f67..b2ae7a60b8 100644 --- a/src/framework/theme/components/chat/chat-message-file.component.ts +++ b/src/framework/theme/components/chat/chat-message-file.component.ts @@ -23,7 +23,7 @@ import { DomSanitizer } from '@angular/platform-browser'; @@ -31,7 +31,7 @@ import { DomSanitizer } from '@angular/platform-browser'; - +
diff --git a/src/framework/theme/components/chat/chat-message-map.component.ts b/src/framework/theme/components/chat/chat-message-map.component.ts index e55ee24e0c..3cf6c75285 100644 --- a/src/framework/theme/components/chat/chat-message-map.component.ts +++ b/src/framework/theme/components/chat/chat-message-map.component.ts @@ -57,7 +57,7 @@ export class NbChatMessageMapComponent { // tslint:disable-next-line url: `https://maps.googleapis.com/maps/api/staticmap?center=${this.latitude},${this.longitude}&zoom=12&size=400x400&key=${this.mapKey}`, type: 'image/png', - icon: 'nb-location', + icon: 'location', }; } diff --git a/src/framework/theme/components/chat/chat.module.ts b/src/framework/theme/components/chat/chat.module.ts index 25e4d9be06..a571bbd51c 100644 --- a/src/framework/theme/components/chat/chat.module.ts +++ b/src/framework/theme/components/chat/chat.module.ts @@ -7,6 +7,7 @@ import { ModuleWithProviders, NgModule } from '@angular/core'; import { NbSharedModule } from '../shared/shared.module'; +import { NbIconModule } from '../icon/icon.module'; import { NbChatComponent } from './chat.component'; import { NbChatMessageComponent } from './chat-message.component'; @@ -30,6 +31,7 @@ const NB_CHAT_COMPONENTS = [ @NgModule({ imports: [ NbSharedModule, + NbIconModule, ], declarations: [ ...NB_CHAT_COMPONENTS, diff --git a/src/framework/theme/components/icon/icon.component.ts b/src/framework/theme/components/icon/icon.component.ts index 1148edb80d..aff5cdc62d 100644 --- a/src/framework/theme/components/icon/icon.component.ts +++ b/src/framework/theme/components/icon/icon.component.ts @@ -172,7 +172,10 @@ export class NbIconComponent implements OnChanges, OnInit { renderIcon(name: string, pack?: string, options?: { [name: string]: any }) { const icon = this.iconLibrary.getIcon(name, pack); - this.html = this.sanitizer.bypassSecurityTrustHtml(icon.icon.render(options)); + const content = icon.icon.render(options); + if (content) { + this.html = this.sanitizer.bypassSecurityTrustHtml(content); + } Object.entries(icon.icon.getAttributes(options)).forEach(([attr, value]: [string, string]) => { this.renderer.setAttribute(this.el.nativeElement, attr, value); diff --git a/src/playground/with-layout/chat/bot-replies.ts b/src/playground/with-layout/chat/bot-replies.ts index 23d8cd1765..7b94d45910 100644 --- a/src/playground/with-layout/chat/bot-replies.ts +++ b/src/playground/with-layout/chat/bot-replies.ts @@ -100,7 +100,7 @@ export const botReplies = [ files: [ { url: fileLink, - icon: 'nb-compose', + icon: 'compose', }, { url: '', @@ -111,7 +111,7 @@ export const botReplies = [ type: 'image/jpeg', }, ], - icon: 'nb-compose', + icon: 'compose', user: { name: 'Bot', avatar: botAvatar, @@ -130,10 +130,10 @@ export const botReplies = [ files: [ { url: fileLink, - icon: 'nb-compose', + icon: 'compose', }, ], - icon: 'nb-compose', + icon: 'compose', user: { name: 'Bot', avatar: botAvatar, diff --git a/src/playground/with-layout/chat/chat-conversation-showcase.component.ts b/src/playground/with-layout/chat/chat-conversation-showcase.component.ts index 9f85f64e62..ae27e5ef7e 100644 --- a/src/playground/with-layout/chat/chat-conversation-showcase.component.ts +++ b/src/playground/with-layout/chat/chat-conversation-showcase.component.ts @@ -27,7 +27,7 @@ export class ChatConversationShowcaseComponent { return { url: file.src, type: file.type, - icon: 'nb-compose', + icon: 'compose', }; }); diff --git a/src/playground/with-layout/chat/chat-drop.component.ts b/src/playground/with-layout/chat/chat-drop.component.ts index c5ba3fc182..eb18f8b6da 100644 --- a/src/playground/with-layout/chat/chat-drop.component.ts +++ b/src/playground/with-layout/chat/chat-drop.component.ts @@ -33,7 +33,7 @@ export class ChatDropComponent { return { url: file.src, type: file.type, - icon: 'nb-compose', + icon: 'compose', }; }); diff --git a/src/playground/with-layout/chat/chat-message-types-showcase.component.ts b/src/playground/with-layout/chat/chat-message-types-showcase.component.ts index 9b8f95c275..f108ec6268 100644 --- a/src/playground/with-layout/chat/chat-message-types-showcase.component.ts +++ b/src/playground/with-layout/chat/chat-message-types-showcase.component.ts @@ -51,7 +51,7 @@ import { Component } from '@angular/core'; sender="John Doe" [reply]="true" [date]="date" - [files]="[ { url: 'http://google.com', icon: 'nb-compose' } ]" + [files]="[ { url: 'http://google.com', icon: 'compose' } ]" [avatar]="'https://i.gifer.com/no.gif'"> Date: Fri, 22 Mar 2019 13:43:58 +0300 Subject: [PATCH 12/33] refactor(icons): move services from theme --- .../icons => components/icon}/icon-pack.ts | 0 .../components/icon/icon.component.spec.ts | 59 +++++++++++++ .../theme/components/icon/icon.component.ts | 19 +++- .../theme/components/icon/icon.module.ts | 7 ++ .../theme/components/icon/icon.spec.ts | 88 +++++++++++-------- .../icons => components/icon}/icon.ts | 27 +++--- .../icon}/icons-library.spec.ts | 12 +-- .../icon}/icons-library.ts | 13 ++- src/framework/theme/index.ts | 4 +- .../theme/services/icons/icon.spec.ts | 75 ---------------- src/framework/theme/services/icons/index.ts | 3 - src/framework/theme/services/theme.service.ts | 7 +- src/framework/theme/theme.module.ts | 2 - 13 files changed, 169 insertions(+), 147 deletions(-) rename src/framework/theme/{services/icons => components/icon}/icon-pack.ts (100%) create mode 100644 src/framework/theme/components/icon/icon.component.spec.ts rename src/framework/theme/{services/icons => components/icon}/icon.ts (67%) rename src/framework/theme/{services/icons => components/icon}/icons-library.spec.ts (92%) rename src/framework/theme/{services/icons => components/icon}/icons-library.ts (93%) delete mode 100644 src/framework/theme/services/icons/icon.spec.ts delete mode 100644 src/framework/theme/services/icons/index.ts diff --git a/src/framework/theme/services/icons/icon-pack.ts b/src/framework/theme/components/icon/icon-pack.ts similarity index 100% rename from src/framework/theme/services/icons/icon-pack.ts rename to src/framework/theme/components/icon/icon-pack.ts diff --git a/src/framework/theme/components/icon/icon.component.spec.ts b/src/framework/theme/components/icon/icon.component.spec.ts new file mode 100644 index 0000000000..551c5bdf5c --- /dev/null +++ b/src/framework/theme/components/icon/icon.component.spec.ts @@ -0,0 +1,59 @@ +/** + * @license + * Copyright Akveo. All Rights Reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { Component, ElementRef, Input, ViewChild } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NbIconModule } from './icon.module'; +import { NbIconsLibrary } from './icons-library'; + + +@Component({ + template: ` + + `, +}) +class IconTestComponent { + @ViewChild('iconEl', { read: ElementRef }) iconElement; + + @Input() icon; +} + +describe('Component: NbIcon', () => { + + let iconTestComponent: IconTestComponent; + let fixture: ComponentFixture; + let iconElement: ElementRef; + let iconsLibrary: NbIconsLibrary; + + beforeEach(() => { + + const bed = TestBed.configureTestingModule({ + imports: [ NbIconModule ], + providers: [ NbIconsLibrary ], + declarations: [ IconTestComponent ], + }); + + fixture = bed.createComponent(IconTestComponent); + iconsLibrary = bed.get(NbIconsLibrary); + + iconsLibrary + .registerSvgPack('svg-pack', { home: '' }, { packClass: 'custom-pack' }); + iconsLibrary.setDefaultPack('svg-pack'); + + iconTestComponent = fixture.componentInstance; + iconElement = iconTestComponent.iconElement; + }); + + it('should render icon', () => { + iconTestComponent.icon = 'home'; + fixture.detectChanges(); + const svg = iconElement.nativeElement.querySelector('svg'); + + expect(iconElement.nativeElement.classList.contains('custom-pack')).toBeTruthy(); + expect(svg.innerHTML).toContain(''); + }); +}); diff --git a/src/framework/theme/components/icon/icon.component.ts b/src/framework/theme/components/icon/icon.component.ts index aff5cdc62d..6dff8904a9 100644 --- a/src/framework/theme/components/icon/icon.component.ts +++ b/src/framework/theme/components/icon/icon.component.ts @@ -17,7 +17,7 @@ import { } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; -import { NbIconsLibrary } from '../../services/icons'; +import { NbIconsLibrary } from './icons-library'; /** * Icon component. @@ -110,6 +110,7 @@ export class NbIconComponent implements OnChanges, OnInit { static readonly STATUS_DANGER = 'danger'; private iconDef; + private prevClasses = []; @HostBinding('innerHtml') html: SafeHtml; @@ -177,9 +178,19 @@ export class NbIconComponent implements OnChanges, OnInit { this.html = this.sanitizer.bypassSecurityTrustHtml(content); } - Object.entries(icon.icon.getAttributes(options)).forEach(([attr, value]: [string, string]) => { - this.renderer.setAttribute(this.el.nativeElement, attr, value); - }); + this.assignClasses(icon.icon.getClasses(options)); return icon; } + + protected assignClasses(classes: string[]) { + this.prevClasses.forEach((klass: string) => { + this.renderer.removeClass(this.el.nativeElement, klass); + }); + + classes.forEach((klass: string) => { + this.renderer.addClass(this.el.nativeElement, klass); + }); + + this.prevClasses = classes; + } } diff --git a/src/framework/theme/components/icon/icon.module.ts b/src/framework/theme/components/icon/icon.module.ts index da123c3944..cc22d6270c 100644 --- a/src/framework/theme/components/icon/icon.module.ts +++ b/src/framework/theme/components/icon/icon.module.ts @@ -8,6 +8,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NbIconComponent } from './icon.component'; +import { NbIconsLibrary } from './icons-library'; @NgModule({ imports: [ @@ -21,4 +22,10 @@ import { NbIconComponent } from './icon.component'; ], }) export class NbIconModule { + + constructor(private iconsLibrary: NbIconsLibrary) { + // @breaking-change 4.0.0 remove and replace with eva-icons module + this.iconsLibrary.registerFontPack('nebular', { iconPrefix: 'nb' }); + this.iconsLibrary.setDefaultPack('nebular'); + } } diff --git a/src/framework/theme/components/icon/icon.spec.ts b/src/framework/theme/components/icon/icon.spec.ts index 8a40a9d4d2..f2f086e652 100644 --- a/src/framework/theme/components/icon/icon.spec.ts +++ b/src/framework/theme/components/icon/icon.spec.ts @@ -4,56 +4,72 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -import { Component, ElementRef, Input, ViewChild } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { NbFontIcon, NbSvgIcon } from './icon'; -import { NbIconModule } from './icon.module'; -import { NbIconsLibrary } from '../../services/icons/icons-library'; +describe('icon', () => { + let fontIcon: NbFontIcon; + let svgIcon: NbSvgIcon; -@Component({ - template: ` - - `, -}) -class IconTestComponent { - @ViewChild('iconEl', { read: ElementRef }) iconElement; - @Input() icon; -} + it(`font icon renders`, () => { -describe('Component: NbIcon', () => { + fontIcon = new NbFontIcon('home', 'custom', { + packClass: 'custom-pack', + iconPrefix: 'cp', + }); + + expect(fontIcon.render()).toEqual('custom'); + }); + + it(`font icon getClasses return classes`, () => { + + fontIcon = new NbFontIcon('home', '', { + packClass: 'custom-pack', + }); + + expect(fontIcon.getClasses()).toEqual(['custom-pack', 'home']); + }); + + it(`font icon getClasses return class with prefix`, () => { + + fontIcon = new NbFontIcon('home', '', { + packClass: 'custom-pack', + iconPrefix: 'cp', + }); + + expect(fontIcon.getClasses()).toEqual(['custom-pack', 'cp-home']); + }); + + it(`font icon getClasses return class with name only`, () => { + + fontIcon = new NbFontIcon('home', ''); - let iconTestComponent: IconTestComponent; - let fixture: ComponentFixture; - let iconElement: ElementRef; - let iconsLibrary: NbIconsLibrary; + expect(fontIcon.getClasses()).toEqual(['home']); + }); - beforeEach(() => { + it(`svg icon renders`, () => { - const bed = TestBed.configureTestingModule({ - imports: [ NbIconModule ], - providers: [ NbIconsLibrary ], - declarations: [ IconTestComponent ], + svgIcon = new NbSvgIcon('home', 'content', { + packClass: 'custom-pack', }); - fixture = bed.createComponent(IconTestComponent); - iconsLibrary = bed.get(NbIconsLibrary); + expect(svgIcon.render()).toEqual('content'); + }); - iconsLibrary - .registerSvgPack('svg-pack', { home: '' }, { packClass: 'custom-pack' }); - iconsLibrary.setDefaultPack('svg-pack'); + it(`svg icon getClasses return class`, () => { - iconTestComponent = fixture.componentInstance; - iconElement = iconTestComponent.iconElement; + svgIcon = new NbSvgIcon('home', '', { + packClass: 'custom-pack', + }); + + expect(svgIcon.getClasses()).toEqual(['custom-pack']); }); - it('should render icon', () => { - iconTestComponent.icon = 'home'; - fixture.detectChanges(); - const svg = iconElement.nativeElement.querySelector('svg'); + it(`svg icon getClasses return class without name`, () => { + + svgIcon = new NbSvgIcon('home', ''); - expect(iconElement.nativeElement.classList.contains('custom-pack')).toBeTruthy(); - expect(svg.innerHTML).toContain(''); + expect(svgIcon.getClasses()).toEqual([]); }); }); diff --git a/src/framework/theme/services/icons/icon.ts b/src/framework/theme/components/icon/icon.ts similarity index 67% rename from src/framework/theme/services/icons/icon.ts rename to src/framework/theme/components/icon/icon.ts index 672be827db..2c8a1a1586 100644 --- a/src/framework/theme/services/icons/icon.ts +++ b/src/framework/theme/components/icon/icon.ts @@ -5,7 +5,7 @@ export interface NbIconOptions { } export interface NbIcon { - getAttributes(options?: NbIconOptions): any; + getClasses(options?: NbIconOptions): string[]; render(options?: NbIconOptions): string; } @@ -13,12 +13,16 @@ export class NbFontIcon implements NbIcon { constructor(protected name, protected content: any, protected params: NbIconPackParams = {}) {} - getAttributes(options?: NbIconOptions) { - const name = this.params.iconPrefix ? `${this.params.iconPrefix}-${this.name}` : this.name; + getClasses(options?: NbIconOptions) { + const classes = []; + + if (this.params.packClass) { + classes.push(this.params.packClass); + } - return { - 'class': this.params.packClass ? `${name} ${this.params.packClass}` : name, - }; + const name = this.params.iconPrefix ? `${this.params.iconPrefix}-${this.name}` : this.name; + classes.push(name); + return classes; } render(options?: NbIconOptions): string { @@ -30,14 +34,13 @@ export class NbSvgIcon implements NbIcon { constructor(protected name, protected content: any, protected params: NbIconPackParams = {}) {} - getAttributes(options?: NbIconOptions) { - if (this.params.packClass) { - return { - 'class': `${this.params.packClass}`, - }; + getClasses(options?: NbIconOptions) { + const classes = []; + if (this.params.packClass) { + classes.push(this.params.packClass); } - return {}; + return classes; } render(options?: NbIconOptions): string { diff --git a/src/framework/theme/services/icons/icons-library.spec.ts b/src/framework/theme/components/icon/icons-library.spec.ts similarity index 92% rename from src/framework/theme/services/icons/icons-library.spec.ts rename to src/framework/theme/components/icon/icons-library.spec.ts index f5c6318e6f..f43b732f20 100644 --- a/src/framework/theme/services/icons/icons-library.spec.ts +++ b/src/framework/theme/components/icon/icons-library.spec.ts @@ -40,7 +40,7 @@ describe('icons-library', () => { const icon = iconsLibrary.getSvgIcon('home'); expect(icon.icon.render()).toEqual(''); - expect(icon.icon.getAttributes().class).toEqual('sp'); + expect(icon.icon.getClasses()).toEqual(['sp']); expect(icon.name).toEqual('home'); expect(icon.pack).toEqual('super-pack'); expect(icon.type).toEqual('svg'); @@ -62,7 +62,7 @@ describe('icons-library', () => { const icon = iconsLibrary.getSvgIcon('home'); expect(icon.icon.render()).toEqual('custom'); - expect(icon.icon.getAttributes().class).toEqual('sp'); + expect(icon.icon.getClasses()).toEqual(['sp']); expect(icon.name).toEqual('home'); expect(icon.pack).toEqual('super-pack'); expect(icon.type).toEqual('svg'); @@ -78,8 +78,8 @@ describe('icons-library', () => { .toThrowError(`Icon 'unknown' is not registered in pack 'super-pack'`); }); - it('should throw for unknown pack', () => { - expect(() => iconsLibrary.getSvgIcon('unknown')).toThrowError(`Icon Pack 'undefined' is not registered`); + it('should throw for no default pack', () => { + expect(() => iconsLibrary.getSvgIcon('unknown')).toThrowError('Default pack is not registered.'); }); it('should throw for wrong pack type', () => { @@ -120,7 +120,7 @@ describe('icons-library', () => { const icon = iconsLibrary.getFontIcon('home'); expect(icon.icon.render()).toEqual(''); - expect(icon.icon.getAttributes().class).toEqual('fp-home font'); + expect(icon.icon.getClasses()).toEqual(['font', 'fp-home']); expect(icon.name).toEqual('home'); expect(icon.pack).toEqual('font-pack'); expect(icon.type).toEqual('font'); @@ -137,7 +137,7 @@ describe('icons-library', () => { const svgIcon = iconsLibrary.getIcon('home', 'super-pack'); expect(icon.icon.render()).toEqual(''); - expect(icon.icon.getAttributes().class).toEqual('fp-home font'); + expect(icon.icon.getClasses()).toEqual(['font', 'fp-home']); expect(icon.name).toEqual('home'); expect(icon.pack).toEqual('font-pack'); expect(icon.type).toEqual('font'); diff --git a/src/framework/theme/services/icons/icons-library.ts b/src/framework/theme/components/icon/icons-library.ts similarity index 93% rename from src/framework/theme/services/icons/icons-library.ts rename to src/framework/theme/components/icon/icons-library.ts index f52d5c6cdc..65ad6e5f25 100644 --- a/src/framework/theme/services/icons/icons-library.ts +++ b/src/framework/theme/components/icon/icons-library.ts @@ -19,6 +19,10 @@ function throwPackNotFoundError(name: string) { throw Error(`Icon Pack '${name}' is not registered`); } +function throwNoDefaultPackError() { + throw Error('Default pack is not registered.'); +} + function throwIconNotFoundError(name: string, pack: string) { throw Error(`Icon '${name}' is not registered in pack '${pack}'`); } @@ -26,7 +30,7 @@ function throwIconNotFoundError(name: string, pack: string) { /** * NbIconsLibrary */ -@Injectable() +@Injectable({providedIn: 'root'}) export class NbIconsLibrary { protected packs: Map = new Map(); @@ -116,7 +120,12 @@ export class NbIconsLibrary { const iconsPack = name ? this.packs.get(name) : this.defaultPack; if (!iconsPack) { - throwPackNotFoundError(name); + + if (!this.defaultPack) { + throwNoDefaultPackError(); + } else { + throwPackNotFoundError(name); + } } return iconsPack; } diff --git a/src/framework/theme/index.ts b/src/framework/theme/index.ts index 67dd535931..e9be0892c1 100644 --- a/src/framework/theme/index.ts +++ b/src/framework/theme/index.ts @@ -99,6 +99,8 @@ export * from './components/tree-grid/data-source/tree-grid-data.service'; export * from './components/tree-grid/data-source/tree-grid-filter.service'; export * from './components/tree-grid/data-source/tree-grid.service'; export * from './components/tree-grid/data-source/tree-grid-sort.service'; -export * from './services/icons'; export * from './components/icon/icon.module'; export * from './components/icon/icon.component'; +export * from './components/icon/icon'; +export * from './components/icon/icon-pack'; +export * from './components/icon/icons-library'; diff --git a/src/framework/theme/services/icons/icon.spec.ts b/src/framework/theme/services/icons/icon.spec.ts deleted file mode 100644 index 6266b8db9c..0000000000 --- a/src/framework/theme/services/icons/icon.spec.ts +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @license - * Copyright Akveo. All Rights Reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - */ - -import { NbFontIcon, NbSvgIcon } from './icon'; - - -describe('icon', () => { - let fontIcon: NbFontIcon; - let svgIcon: NbSvgIcon; - - - it(`font icon renders`, () => { - - fontIcon = new NbFontIcon('home', 'custom', { - packClass: 'custom-pack', - iconPrefix: 'cp', - }); - - expect(fontIcon.render()).toEqual('custom'); - }); - - it(`font icon getAttributes return class`, () => { - - fontIcon = new NbFontIcon('home', '', { - packClass: 'custom-pack', - }); - - expect(fontIcon.getAttributes().class).toEqual('home custom-pack'); - }); - - it(`font icon getAttributes return class with prefix`, () => { - - fontIcon = new NbFontIcon('home', '', { - packClass: 'custom-pack', - iconPrefix: 'cp', - }); - - expect(fontIcon.getAttributes().class).toEqual('cp-home custom-pack'); - }); - - it(`font icon getAttributes return class with name only`, () => { - - fontIcon = new NbFontIcon('home', ''); - - expect(fontIcon.getAttributes().class).toEqual('home'); - }); - - it(`svg icon renders`, () => { - - svgIcon = new NbSvgIcon('home', 'content', { - packClass: 'custom-pack', - }); - - expect(svgIcon.render()).toEqual('content'); - }); - - it(`svg icon getAttributes return class`, () => { - - svgIcon = new NbSvgIcon('home', '', { - packClass: 'custom-pack', - }); - - expect(svgIcon.getAttributes().class).toEqual('custom-pack'); - }); - - it(`font icon getAttributes return class with name only`, () => { - - svgIcon = new NbSvgIcon('home', ''); - - expect(svgIcon.getAttributes()).toEqual({}); - }); -}); diff --git a/src/framework/theme/services/icons/index.ts b/src/framework/theme/services/icons/index.ts deleted file mode 100644 index c8611559f7..0000000000 --- a/src/framework/theme/services/icons/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './icon'; -export * from './icon-pack'; -export * from './icons-library'; diff --git a/src/framework/theme/services/theme.service.ts b/src/framework/theme/services/theme.service.ts index cd3f564603..10fcff1be5 100644 --- a/src/framework/theme/services/theme.service.ts +++ b/src/framework/theme/services/theme.service.ts @@ -13,7 +13,6 @@ import { NB_THEME_OPTIONS } from '../theme.options'; import { NbJSThemeOptions } from './js-themes/theme.options'; import { NbJSThemesRegistry } from './js-themes-registry.service'; import { NbMediaBreakpointsService, NbMediaBreakpoint } from './breakpoints.service'; -import { NbIconsLibrary } from './icons/icons-library'; /** * Main Nebular service. Includes various helper methods. @@ -30,14 +29,10 @@ export class NbThemeService { constructor(@Inject(NB_THEME_OPTIONS) protected options: any, private breakpointService: NbMediaBreakpointsService, - private jsThemesRegistry: NbJSThemesRegistry, - private iconsLibrary: NbIconsLibrary) { + private jsThemesRegistry: NbJSThemesRegistry) { if (options && options.name) { this.changeTheme(options.name); } - // @breaking-change 4.0.0 remove and replace with eva-icons module - this.iconsLibrary.registerFontPack('nebular', { iconPrefix: 'nb' }); - this.iconsLibrary.setDefaultPack('nebular'); } /** diff --git a/src/framework/theme/theme.module.ts b/src/framework/theme/theme.module.ts index 5501067332..9344925b28 100644 --- a/src/framework/theme/theme.module.ts +++ b/src/framework/theme/theme.module.ts @@ -29,7 +29,6 @@ import { NbLayoutDirectionService, NbLayoutDirection, NB_LAYOUT_DIRECTION } from import { NbLayoutScrollService } from './services/scroll.service'; import { NbLayoutRulerService } from './services/ruler.service'; import { NbOverlayModule } from './components/cdk'; -import { NbIconsLibrary } from './services/icons/icons-library'; export function nbWindowFactory() { return window; @@ -70,7 +69,6 @@ export class NbThemeModule { { provide: NB_WINDOW, useFactory: nbWindowFactory }, { provide: NB_DOCUMENT, useExisting: DOCUMENT }, NbJSThemesRegistry, - NbIconsLibrary, NbThemeService, NbMediaBreakpointsService, NbSpinnerService, From 7cb01912b3f90a67ee8d6b79083eecc59bd98d18 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Fri, 22 Mar 2019 13:44:21 +0300 Subject: [PATCH 13/33] refactor(menu): use nb-icon instead of span --- .../theme/components/menu/menu-item.component.html | 13 ++++++------- src/framework/theme/components/menu/menu.module.ts | 3 ++- src/framework/theme/components/menu/menu.spec.ts | 2 +- .../with-layout/menu/menu-showcase.component.ts | 4 ++++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/framework/theme/components/menu/menu-item.component.html b/src/framework/theme/components/menu/menu-item.component.html index c3bb5f4081..ff00cec765 100644 --- a/src/framework/theme/components/menu/menu-item.component.html +++ b/src/framework/theme/components/menu/menu-item.component.html @@ -1,5 +1,5 @@ - + {{ menuItem.title }} - + {{ menuItem.title }} - + {{ menuItem.title }} - + {{ menuItem.title }} - + {{ menuItem.title }} - +