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()"> - {{ buttonTitle }} + {{ buttonTitle }} `, @@ -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'; 1"> - + @@ -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 }} - + { it('should set icon to menu item', () => { const { fixture } = createSingleMenuComponent([{ title: 'Home', icon: 'test-icon' }]); const iconWrapper = fixture.nativeElement.querySelector('.menu-icon'); - expect(iconWrapper.classList).toContain('test-icon'); + expect(iconWrapper.classList).toContain('nb-test-icon'); }); it('should set title to menu item', () => { diff --git a/src/playground/with-layout/menu/menu-showcase.component.ts b/src/playground/with-layout/menu/menu-showcase.component.ts index 37235f6983..3adebcbe75 100644 --- a/src/playground/with-layout/menu/menu-showcase.component.ts +++ b/src/playground/with-layout/menu/menu-showcase.component.ts @@ -16,18 +16,22 @@ export class MenuShowcaseComponent { items = [ { title: 'Profile', + icon: 'person', link: [], }, { title: 'Change Password', + icon: 'locked', link: [], }, { title: 'Privacy Policy', + icon: 'checkmark', link: [], }, { title: 'Logout', + icon: 'arrow-thin-left', link: [], }, ]; From 8ba2f64fb2139674284d7f59f66382cbecdca7bd Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Fri, 22 Mar 2019 14:05:09 +0300 Subject: [PATCH 14/33] refactor(tabs): use nb-icon instead of span --- .../route-tabset/route-tabset.component.scss | 4 ++-- .../route-tabset/route-tabset.component.ts | 6 +++--- .../route-tabset/route-tabset.module.ts | 2 ++ .../components/tabset/tabset.component.ts | 2 +- .../theme/components/tabset/tabset.module.ts | 2 ++ .../tabset/route-tabset-showcase.component.ts | 6 +++--- .../tabset/tabset-icon.component.html | 18 +++++++++--------- 7 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/framework/theme/components/route-tabset/route-tabset.component.scss b/src/framework/theme/components/route-tabset/route-tabset.component.scss index fb30b44a16..ce53f16ebd 100644 --- a/src/framework/theme/components/route-tabset/route-tabset.component.scss +++ b/src/framework/theme/components/route-tabset/route-tabset.component.scss @@ -36,12 +36,12 @@ left: 0; } - i { + nb-icon { font-size: 1.5rem; vertical-align: middle; } - i + span { + nb-icon + span { @include nb-ltr(margin-left, 0.5rem); @include nb-rtl(margin-right, 0.5rem); } diff --git a/src/framework/theme/components/route-tabset/route-tabset.component.ts b/src/framework/theme/components/route-tabset/route-tabset.component.ts index 270cddd9a3..7a8ee62e73 100644 --- a/src/framework/theme/components/route-tabset/route-tabset.component.ts +++ b/src/framework/theme/components/route-tabset/route-tabset.component.ts @@ -16,7 +16,7 @@ import { convertToBoolProperty } from '../helpers'; * { * title: 'Route tab #1', * route: '/pages/description', - * icon: 'nb-home', + * icon: 'home', * responsive: true, // hide title before `route-tabs-icon-only-max-width` value * }, * { @@ -68,7 +68,7 @@ import { convertToBoolProperty } from '../helpers'; class="route-tab disabled" tabindex="-1"> - + {{ tab.title }} @@ -82,7 +82,7 @@ import { convertToBoolProperty } from '../helpers'; tabindex="0" class="route-tab"> - + {{ tab.title }} diff --git a/src/framework/theme/components/route-tabset/route-tabset.module.ts b/src/framework/theme/components/route-tabset/route-tabset.module.ts index a0f96e883f..47c5b54d3d 100644 --- a/src/framework/theme/components/route-tabset/route-tabset.module.ts +++ b/src/framework/theme/components/route-tabset/route-tabset.module.ts @@ -9,10 +9,12 @@ import { NgModule } from '@angular/core'; import { NbSharedModule } from '../shared/shared.module'; import { NbRouteTabsetComponent } from './route-tabset.component'; +import { NbIconModule } from '../icon/icon.module'; @NgModule({ imports: [ NbSharedModule, + NbIconModule, ], declarations: [ NbRouteTabsetComponent, diff --git a/src/framework/theme/components/tabset/tabset.component.ts b/src/framework/theme/components/tabset/tabset.component.ts index a367ed9f71..e424c2f615 100644 --- a/src/framework/theme/components/tabset/tabset.component.ts +++ b/src/framework/theme/components/tabset/tabset.component.ts @@ -222,7 +222,7 @@ export class NbTabComponent { [attr.tabindex]="tab.disabled ? -1 : 0" class="tab"> - + {{ tab.tabTitle }} - + List of users. - + List of orders. - + List of transactions. @@ -20,13 +20,13 @@ - + List of users. - + List of orders. - + List of transactions. @@ -38,13 +38,13 @@ - + List of users. - + List of orders. - + List of transactions. From 4e8f5cffbc2b4cb08956c0dc0e0bf1219e9afa80 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Fri, 22 Mar 2019 14:06:55 +0300 Subject: [PATCH 15/33] refactor(stepper): use nb-icon instead of span --- .../theme/components/stepper/_stepper.component.theme.scss | 2 +- src/framework/theme/components/stepper/stepper.component.html | 2 +- src/framework/theme/components/stepper/stepper.module.ts | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/components/stepper/_stepper.component.theme.scss b/src/framework/theme/components/stepper/_stepper.component.theme.scss index 36178ad3ca..28f532ff7d 100644 --- a/src/framework/theme/components/stepper/_stepper.component.theme.scss +++ b/src/framework/theme/components/stepper/_stepper.component.theme.scss @@ -48,7 +48,7 @@ color: nb-theme(stepper-fg); font-weight: nb-theme(stepper-label-font-weight); - .icon { + nb-icon { font-size: nb-theme(stepper-completed-icon-size); font-weight: nb-theme(stepper-completed-icon-weight); } diff --git a/src/framework/theme/components/stepper/stepper.component.html b/src/framework/theme/components/stepper/stepper.component.html index 5f712a0668..140082d556 100644 --- a/src/framework/theme/components/stepper/stepper.component.html +++ b/src/framework/theme/components/stepper/stepper.component.html @@ -13,7 +13,7 @@ (click)="!disableStepNavigation && step.select()"> {{ index + 1 }} - + diff --git a/src/framework/theme/components/stepper/stepper.module.ts b/src/framework/theme/components/stepper/stepper.module.ts index 168069c38d..2785ec5660 100644 --- a/src/framework/theme/components/stepper/stepper.module.ts +++ b/src/framework/theme/components/stepper/stepper.module.ts @@ -10,10 +10,12 @@ import { NbSharedModule } from '../shared/shared.module'; import { NbStepperComponent } from './stepper.component'; import { NbStepComponent } from './step.component'; import { NbStepperNextDirective, NbStepperPreviousDirective } from './stepper-button.directive'; +import { NbIconModule } from '../icon/icon.module'; @NgModule({ imports: [ NbSharedModule, + NbIconModule, ], declarations: [ NbStepperComponent, From 7b8a258287ab23bed2ad240786767b1bc85e075c Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Fri, 22 Mar 2019 14:17:29 +0300 Subject: [PATCH 16/33] refactor(toastr): use nb-icon instead of span --- .../toastr/_toast.component.theme.scss | 22 +++++++++---------- .../components/toastr/toast.component.html | 2 +- .../components/toastr/toast.component.scss | 2 +- .../theme/components/toastr/toastr-config.ts | 12 +++++----- .../theme/components/toastr/toastr.module.ts | 3 ++- .../toastr/toastr-icon.component.ts | 2 +- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/framework/theme/components/toastr/_toast.component.theme.scss b/src/framework/theme/components/toastr/_toast.component.theme.scss index 9386c29b81..b040d96902 100644 --- a/src/framework/theme/components/toastr/_toast.component.theme.scss +++ b/src/framework/theme/components/toastr/_toast.component.theme.scss @@ -12,7 +12,7 @@ border: nb-theme(toastr-border); border-radius: nb-theme(toastr-border-radius); - .icon { + nb-icon { @include nb-ltr(margin-right, 1.25rem); @include nb-rtl(margin-left, 1.25rem); } @@ -39,7 +39,7 @@ border-color: nb-theme(color-success); color: nb-theme(color-success); - i { + nb-icon { background-color: nb-theme(color-success); color: nb-theme(color-white); @@ -49,7 +49,7 @@ @include btn-hero-success-gradient(); color: nb-theme(toastr-color-fg); - i { + nb-icon { background-color: nb-theme(color-white); color: nb-theme(color-success); @@ -61,7 +61,7 @@ border-color: nb-theme(color-info); color: nb-theme(color-info); - i { + nb-icon { background-color: nb-theme(color-info); color: nb-theme(color-white); @@ -71,7 +71,7 @@ @include btn-hero-info-gradient(); color: nb-theme(toastr-color-fg); - i { + nb-icon { background-color: nb-theme(color-white); color: nb-theme(color-info); @@ -83,7 +83,7 @@ border-color: nb-theme(color-warning); color: nb-theme(color-warning); - i { + nb-icon { background-color: nb-theme(color-warning); color: nb-theme(color-white); @@ -93,7 +93,7 @@ @include btn-hero-warning-gradient(); color: nb-theme(toastr-color-fg); - i { + nb-icon { background-color: nb-theme(color-white); color: nb-theme(color-warning); @@ -105,7 +105,7 @@ border-color: nb-theme(color-primary); color: nb-theme(color-primary); - i { + nb-icon { background-color: nb-theme(color-primary); color: nb-theme(color-white); @@ -115,7 +115,7 @@ @include btn-hero-primary-gradient(); color: nb-theme(toastr-color-fg); - i { + nb-icon { background-color: nb-theme(color-white); color: nb-theme(color-primary); @@ -127,7 +127,7 @@ border-color: nb-theme(color-danger); color: nb-theme(color-danger); - i { + nb-icon { background-color: nb-theme(color-danger); color: nb-theme(color-white); @@ -137,7 +137,7 @@ @include btn-hero-danger-gradient(); color: nb-theme(toastr-color-fg); - i { + nb-icon { background-color: nb-theme(color-white); color: nb-theme(color-danger); diff --git a/src/framework/theme/components/toastr/toast.component.html b/src/framework/theme/components/toastr/toast.component.html index 4df2d1009a..3cdb22182d 100644 --- a/src/framework/theme/components/toastr/toast.component.html +++ b/src/framework/theme/components/toastr/toast.component.html @@ -1,4 +1,4 @@ - + {{ toast.title }} {{ toast.message }} diff --git a/src/framework/theme/components/toastr/toast.component.scss b/src/framework/theme/components/toastr/toast.component.scss index 51946e71db..d6cd2721ed 100644 --- a/src/framework/theme/components/toastr/toast.component.scss +++ b/src/framework/theme/components/toastr/toast.component.scss @@ -39,7 +39,7 @@ } } - .icon { + nb-icon { font-size: 2.5rem; } diff --git a/src/framework/theme/components/toastr/toastr-config.ts b/src/framework/theme/components/toastr/toastr-config.ts index 98d7b77ddf..400e0b8b18 100644 --- a/src/framework/theme/components/toastr/toastr-config.ts +++ b/src/framework/theme/components/toastr/toastr-config.ts @@ -43,16 +43,16 @@ export class NbToastrConfig { /** * Icon class that can be provided to render custom icon. * */ - icon: string = 'nb-email'; + icon: string = 'email'; /** * Toast status icon-class mapping. * */ protected icons = { - [NbToastStatus.DANGER]: 'nb-danger', - [NbToastStatus.SUCCESS]: 'nb-checkmark-circle', - [NbToastStatus.INFO]: 'nb-help', - [NbToastStatus.WARNING]: 'nb-alert', - [NbToastStatus.PRIMARY]: 'nb-email', + [NbToastStatus.DANGER]: 'danger', + [NbToastStatus.SUCCESS]: 'checkmark-circle', + [NbToastStatus.INFO]: 'help', + [NbToastStatus.WARNING]: 'alert', + [NbToastStatus.PRIMARY]: 'email', }; constructor(config: Partial) { diff --git a/src/framework/theme/components/toastr/toastr.module.ts b/src/framework/theme/components/toastr/toastr.module.ts index 58a24f5d56..37994e2c82 100644 --- a/src/framework/theme/components/toastr/toastr.module.ts +++ b/src/framework/theme/components/toastr/toastr.module.ts @@ -8,6 +8,7 @@ import { ModuleWithProviders, NgModule } from '@angular/core'; import { NbOverlayModule } from '../cdk'; import { NbSharedModule } from '../shared/shared.module'; +import { NbIconModule } from '../icon/icon.module'; import { NbToastrContainerRegistry, NbToastrService } from './toastr.service'; import { NbToastComponent } from './toast.component'; @@ -16,7 +17,7 @@ import { NB_TOASTR_CONFIG, NbToastrConfig } from './toastr-config'; @NgModule({ - imports: [NbSharedModule, NbOverlayModule], + imports: [NbSharedModule, NbOverlayModule, NbIconModule], declarations: [NbToastrContainerComponent, NbToastComponent], entryComponents: [NbToastrContainerComponent, NbToastComponent], }) diff --git a/src/playground/with-layout/toastr/toastr-icon.component.ts b/src/playground/with-layout/toastr/toastr-icon.component.ts index 160efdf482..bfbe229116 100644 --- a/src/playground/with-layout/toastr/toastr-icon.component.ts +++ b/src/playground/with-layout/toastr/toastr-icon.component.ts @@ -6,7 +6,7 @@ import { NbToastrService } from '@nebular/theme'; template: ` With icon Without icon - Custom icon + Custom icon `, styles: [ ` From a4cd78e04221db2d59e260278e5ea694974c946b Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Fri, 22 Mar 2019 14:25:05 +0300 Subject: [PATCH 17/33] refactor(tooltip): use nb-icon instead of span --- .../theme/components/tooltip/tooltip.component.scss | 6 +++--- .../theme/components/tooltip/tooltip.component.ts | 2 +- src/framework/theme/components/tooltip/tooltip.module.ts | 8 +++++--- src/framework/theme/components/tooltip/tooltip.spec.ts | 8 ++++---- .../with-layout/tooltip/tooltip-with-icon.component.html | 4 ++-- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/framework/theme/components/tooltip/tooltip.component.scss b/src/framework/theme/components/tooltip/tooltip.component.scss index a5e0129bd8..407319f3e0 100644 --- a/src/framework/theme/components/tooltip/tooltip.component.scss +++ b/src/framework/theme/components/tooltip/tooltip.component.scss @@ -26,7 +26,7 @@ height: 0; } - .icon { + nb-icon { font-size: 1.25rem; } @@ -34,10 +34,10 @@ line-height: 1.25rem; } - .icon + span { + nb-icon + span { margin-left: 0.5rem; } - &.right .icon + span { + &.right nb-icon + span { margin-right: 0.5rem; } diff --git a/src/framework/theme/components/tooltip/tooltip.component.ts b/src/framework/theme/components/tooltip/tooltip.component.ts index 25deaec704..0594c564ec 100644 --- a/src/framework/theme/components/tooltip/tooltip.component.ts +++ b/src/framework/theme/components/tooltip/tooltip.component.ts @@ -33,7 +33,7 @@ import { animate, state, style, transition, trigger } from '@angular/animations' template: ` - + {{ content }} `, diff --git a/src/framework/theme/components/tooltip/tooltip.module.ts b/src/framework/theme/components/tooltip/tooltip.module.ts index dba81f2bf1..817cf0148c 100644 --- a/src/framework/theme/components/tooltip/tooltip.module.ts +++ b/src/framework/theme/components/tooltip/tooltip.module.ts @@ -6,14 +6,16 @@ import { NgModule } from '@angular/core'; -import { NbTooltipComponent } from './tooltip.component'; import { NbSharedModule } from '../shared/shared.module'; -import { NbTooltipDirective } from './tooltip.directive'; import { NbOverlayModule } from '../cdk'; +import { NbIconModule } from '../icon/icon.module'; + +import { NbTooltipComponent } from './tooltip.component'; +import { NbTooltipDirective } from './tooltip.directive'; @NgModule({ - imports: [NbSharedModule, NbOverlayModule], + imports: [NbSharedModule, NbOverlayModule, NbIconModule], declarations: [NbTooltipComponent, NbTooltipDirective], exports: [NbTooltipDirective], entryComponents: [NbTooltipComponent], diff --git a/src/framework/theme/components/tooltip/tooltip.spec.ts b/src/framework/theme/components/tooltip/tooltip.spec.ts index 56d1b7e81a..d32cc0357f 100644 --- a/src/framework/theme/components/tooltip/tooltip.spec.ts +++ b/src/framework/theme/components/tooltip/tooltip.spec.ts @@ -381,7 +381,7 @@ describe('Directive: NbTooltipDirective', () => { fixture.componentInstance.trigger = NbTrigger.CLICK; fixture.componentInstance.content = 'new string'; fixture.componentInstance.status = 'success'; - fixture.componentInstance.icon = 'nb-home'; + fixture.componentInstance.icon = 'home'; fixture.componentInstance.position = NbPosition.LEFT; fixture.detectChanges(); @@ -401,7 +401,7 @@ describe('Directive: NbTooltipDirective', () => { expect(contentSpy).toHaveBeenCalledTimes(3); expect(contentSpy).toHaveBeenCalledWith('new string'); expect(contextSpy).toHaveBeenCalledTimes(3); - expect(contextSpy).toHaveBeenCalledWith({ status: 'success', icon: 'nb-home' }); + expect(contextSpy).toHaveBeenCalledWith({ status: 'success', icon: 'home' }); expect(buildSpy).toHaveBeenCalledTimes(1); expect(rebuildSpy).toHaveBeenCalledTimes(2); }); @@ -447,7 +447,7 @@ describe('Directive: NbTooltipDirective', () => { fixture.componentInstance.tooltip.trigger = NbTrigger.CLICK; fixture.componentInstance.tooltip.content = 'new string'; fixture.componentInstance.tooltip.status = 'success'; - fixture.componentInstance.tooltip.icon = 'nb-home'; + fixture.componentInstance.tooltip.icon = 'home'; fixture.componentInstance.tooltip.position = NbPosition.LEFT; fixture.componentInstance.tooltip.rebuild(); @@ -467,7 +467,7 @@ describe('Directive: NbTooltipDirective', () => { expect(contentSpy).toHaveBeenCalledTimes(3); expect(contentSpy).toHaveBeenCalledWith('new string'); expect(contextSpy).toHaveBeenCalledTimes(3); - expect(contextSpy).toHaveBeenCalledWith({ status: 'success', icon: 'nb-home' }); + expect(contextSpy).toHaveBeenCalledWith({ status: 'success', icon: 'home' }); expect(buildSpy).toHaveBeenCalledTimes(1); expect(rebuildSpy).toHaveBeenCalledTimes(2); }); diff --git a/src/playground/with-layout/tooltip/tooltip-with-icon.component.html b/src/playground/with-layout/tooltip/tooltip-with-icon.component.html index 2ecdc5964e..48e4f7f761 100644 --- a/src/playground/with-layout/tooltip/tooltip-with-icon.component.html +++ b/src/playground/with-layout/tooltip/tooltip-with-icon.component.html @@ -1,2 +1,2 @@ -Show Tooltip -Show Tooltip +Show Tooltip +Show Tooltip From c85055ad2f2cef8332b894ebd138ee91cfb1c219 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Fri, 22 Mar 2019 15:21:43 +0300 Subject: [PATCH 18/33] refactor(tree-grid): use nb-icon instead of span --- .../components/tree-grid/_tree-grid.component.theme.scss | 8 ++++++-- .../tree-grid/tree-grid-row-toggle.component.ts | 2 +- .../components/tree-grid/tree-grid-sort.component.ts | 7 ++----- .../theme/components/tree-grid/tree-grid.module.ts | 3 ++- .../with-layout/tree-grid/components/fs-icon.component.ts | 2 +- src/playground/with-layout/tree-grid/tree-grid.module.ts | 4 ++-- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/framework/theme/components/tree-grid/_tree-grid.component.theme.scss b/src/framework/theme/components/tree-grid/_tree-grid.component.theme.scss index 47d4cfd8c5..a3b662c499 100644 --- a/src/framework/theme/components/tree-grid/_tree-grid.component.theme.scss +++ b/src/framework/theme/components/tree-grid/_tree-grid.component.theme.scss @@ -17,6 +17,10 @@ height: nb-theme(tree-grid-row-min-height); padding: nb-theme(tree-grid-cell-padding); border: $border-width $border-style $border-color; + + nb-icon { + font-size: 1rem; + } } .nb-tree-grid-header-row { @@ -37,8 +41,8 @@ } } - nb-tree-grid-row-toggle .row-toggle-button .icon, - nb-sort-icon .icon { + nb-tree-grid-row-toggle .row-toggle-button nb-icon, + nb-sort-icon nb-icon { color: nb-theme(tree-grid-icon-color); } diff --git a/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts b/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts index 5776c1e455..30bc69ea88 100644 --- a/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts +++ b/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts @@ -14,7 +14,7 @@ import { NbTreeGridCellDirective } from './tree-grid-cell.component'; selector: 'nb-tree-grid-row-toggle', template: ` - + `, styles: [` diff --git a/src/framework/theme/components/tree-grid/tree-grid-sort.component.ts b/src/framework/theme/components/tree-grid/tree-grid-sort.component.ts index 7adcfa0045..046bcf72f1 100644 --- a/src/framework/theme/components/tree-grid/tree-grid-sort.component.ts +++ b/src/framework/theme/components/tree-grid/tree-grid-sort.component.ts @@ -82,11 +82,8 @@ export class NbSortHeaderIconDirective {} selector: 'nb-sort-icon', template: ` - - + + `, }) diff --git a/src/framework/theme/components/tree-grid/tree-grid.module.ts b/src/framework/theme/components/tree-grid/tree-grid.module.ts index bce3456b62..787647063f 100644 --- a/src/framework/theme/components/tree-grid/tree-grid.module.ts +++ b/src/framework/theme/components/tree-grid/tree-grid.module.ts @@ -8,6 +8,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NbTableModule } from '../cdk/table'; +import { NbIconModule } from '../icon/icon.module'; import { NbTreeGridComponent } from './tree-grid.component'; import { NbTreeGridCellDefDirective, @@ -79,7 +80,7 @@ const COMPONENTS = [ ]; @NgModule({ - imports: [ CommonModule, NbTableModule ], + imports: [ CommonModule, NbTableModule, NbIconModule ], declarations: [ ...COMPONENTS ], exports: [ NbTableModule, ...COMPONENTS ], providers: [ diff --git a/src/playground/with-layout/tree-grid/components/fs-icon.component.ts b/src/playground/with-layout/tree-grid/components/fs-icon.component.ts index 662ae9ec9c..844713486e 100644 --- a/src/playground/with-layout/tree-grid/components/fs-icon.component.ts +++ b/src/playground/with-layout/tree-grid/components/fs-icon.component.ts @@ -6,7 +6,7 @@ import { Component, Input } from '@angular/core'; - + `, }) diff --git a/src/playground/with-layout/tree-grid/tree-grid.module.ts b/src/playground/with-layout/tree-grid/tree-grid.module.ts index bb1b28d0be..bd06502e5b 100644 --- a/src/playground/with-layout/tree-grid/tree-grid.module.ts +++ b/src/playground/with-layout/tree-grid/tree-grid.module.ts @@ -6,7 +6,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { NbCardModule, NbInputModule, NbTreeGridModule } from '@nebular/theme'; +import { NbCardModule, NbIconModule, NbInputModule, NbTreeGridModule } from '@nebular/theme'; import { TreeGridShowcaseComponent } from './tree-grid-showcase.component'; import { TreeGridRoutingModule } from './tree-grid-routing.module'; @@ -20,7 +20,7 @@ import { TreeGridDisableClickToggleComponent } from './tree-grid-disable-click-t import { TreeGridCustomNodeStructureComponent } from './tree-grid-custom-node-structure.component'; @NgModule({ - imports: [ CommonModule, NbTreeGridModule, TreeGridRoutingModule, NbCardModule, NbInputModule ], + imports: [ CommonModule, NbTreeGridModule, TreeGridRoutingModule, NbCardModule, NbInputModule, NbIconModule ], declarations: [ FsIconComponent, TreeGridShowcaseComponent, From 87760f73091464fff6ed44f967af10c8d8a8fe56 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Fri, 22 Mar 2019 15:21:51 +0300 Subject: [PATCH 19/33] refactor(auth): use nb-icon instead of span --- src/framework/auth/auth.module.ts | 2 ++ src/framework/auth/components/auth.component.scss | 2 +- src/framework/auth/components/auth.component.ts | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/framework/auth/auth.module.ts b/src/framework/auth/auth.module.ts index b61fdaaff1..082d695b62 100644 --- a/src/framework/auth/auth.module.ts +++ b/src/framework/auth/auth.module.ts @@ -9,6 +9,7 @@ import { NbButtonModule, NbCardModule, NbCheckboxModule, + NbIconModule, NbInputModule, NbLayoutModule, } from '@nebular/theme'; @@ -94,6 +95,7 @@ export function nbNoOpInterceptorFilter(req: HttpRequest): boolean { NbButtonModule, RouterModule, FormsModule, + NbIconModule, ], declarations: [ NbAuthComponent, diff --git a/src/framework/auth/components/auth.component.scss b/src/framework/auth/components/auth.component.scss index d2c4f9f20b..ce6b0c4cb1 100644 --- a/src/framework/auth/components/auth.component.scss +++ b/src/framework/auth/components/auth.component.scss @@ -11,7 +11,7 @@ .navigation .link { text-decoration: none; - .icon { + nb-icon { font-size: 2rem; } } diff --git a/src/framework/auth/components/auth.component.ts b/src/framework/auth/components/auth.component.ts index cd5e020619..aa432f7722 100644 --- a/src/framework/auth/components/auth.component.ts +++ b/src/framework/auth/components/auth.component.ts @@ -18,7 +18,7 @@ import { takeWhile } from 'rxjs/operators'; - + From 90555e7503074512b041e2a5b2b3651c0eca945b Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Mon, 25 Mar 2019 18:38:46 +0300 Subject: [PATCH 20/33] refactor(theme): default svg pack for built in components --- 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 | 32 ++++++++++ .../accordion/_accordion.component.theme.scss | 2 +- .../accordion-item-header.component.ts | 2 +- .../components/accordion/accordion.module.ts | 3 +- .../theme/components/card/card.module.ts | 3 +- .../card/flip-card/flip-card.component.ts | 4 +- .../card/reveal-card/reveal-card.component.ts | 2 +- .../chat/_chat.component.theme.scss | 7 ++- .../components/chat/chat-form.component.ts | 6 +- .../chat/chat-message-file.component.ts | 2 +- .../icon/_icon.component.theme.scss | 2 + .../theme/components/icon/icon.module.ts | 31 ++++++++- .../components/icon/icons-library.spec.ts | 10 ++- .../theme/components/icon/icons-library.ts | 6 +- .../components/menu/menu-item.component.html | 2 +- .../components/search/search.component.ts | 4 +- .../theme/components/search/search.module.ts | 2 + .../components/stepper/stepper.component.html | 2 +- .../toastr/_toast.component.theme.scss | 44 ++++++------- .../components/toastr/toast.component.html | 4 +- .../components/toastr/toast.component.ts | 4 ++ .../theme/components/toastr/toastr-config.ts | 16 +++-- .../tree-grid/_tree-grid.component.theme.scss | 21 +++++-- .../tree-grid-row-toggle.component.ts | 2 +- .../tree-grid/tree-grid-sort.component.ts | 4 +- .../components/window/window.component.ts | 8 +-- .../theme/components/window/window.module.ts | 3 +- .../theme/styles/themes/_default.scss | 6 +- .../icon/icon-showcase.component.ts | 3 + 32 files changed, 237 insertions(+), 71 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 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..7b5792cc10 --- /dev/null +++ b/src/framework/eva-icons/package.json @@ -0,0 +1,32 @@ +{ + "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", + "icons", + "theme", + "nebular", + "eva-icons" + ], + "peerDependencies": { + "@nebular/theme": "3.4.0", + "eva-icons": "^1.1.1" + } +} diff --git a/src/framework/theme/components/accordion/_accordion.component.theme.scss b/src/framework/theme/components/accordion/_accordion.component.theme.scss index 0f56682f43..f494583a47 100644 --- a/src/framework/theme/components/accordion/_accordion.component.theme.scss +++ b/src/framework/theme/components/accordion/_accordion.component.theme.scss @@ -29,7 +29,7 @@ position: relative; @include nb-accordion-item-header(); - i { + nb-icon { position: absolute; @include nb-ltr(right, 1rem); @include nb-rtl(left, 1rem); diff --git a/src/framework/theme/components/accordion/accordion-item-header.component.ts b/src/framework/theme/components/accordion/accordion-item-header.component.ts index cd6f0e87b1..d1b7581049 100644 --- a/src/framework/theme/components/accordion/accordion-item-header.component.ts +++ b/src/framework/theme/components/accordion/accordion-item-header.component.ts @@ -29,7 +29,7 @@ import { NbAccordionItemComponent } from './accordion-item.component'; - + `, animations: [ trigger('expansionIndicator', [ diff --git a/src/framework/theme/components/accordion/accordion.module.ts b/src/framework/theme/components/accordion/accordion.module.ts index 34ab98cdb9..ccf8a104f0 100644 --- a/src/framework/theme/components/accordion/accordion.module.ts +++ b/src/framework/theme/components/accordion/accordion.module.ts @@ -7,6 +7,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { NbIconModule } from '../icon/icon.module'; import { NbAccordionComponent } from './accordion.component'; import { NbAccordionItemComponent } from './accordion-item.component'; import { NbAccordionItemHeaderComponent } from './accordion-item-header.component'; @@ -20,7 +21,7 @@ const NB_ACCORDION_COMPONENTS = [ ]; @NgModule({ - imports: [CommonModule], + imports: [CommonModule, NbIconModule], exports: [...NB_ACCORDION_COMPONENTS], declarations: [...NB_ACCORDION_COMPONENTS], providers: [], diff --git a/src/framework/theme/components/card/card.module.ts b/src/framework/theme/components/card/card.module.ts index 5a1873058f..deeef96ee4 100644 --- a/src/framework/theme/components/card/card.module.ts +++ b/src/framework/theme/components/card/card.module.ts @@ -7,7 +7,7 @@ import { NgModule } from '@angular/core'; import { NbSharedModule } from '../shared/shared.module'; - +import { NbIconModule } from '../icon/icon.module'; import { NbCardComponent, NbCardBodyComponent, @@ -33,6 +33,7 @@ const NB_CARD_COMPONENTS = [ @NgModule({ imports: [ NbSharedModule, + NbIconModule, ], declarations: [ ...NB_CARD_COMPONENTS, diff --git a/src/framework/theme/components/card/flip-card/flip-card.component.ts b/src/framework/theme/components/card/flip-card/flip-card.component.ts index f8ceff734d..78f3329e1c 100644 --- a/src/framework/theme/components/card/flip-card/flip-card.component.ts +++ b/src/framework/theme/components/card/flip-card/flip-card.component.ts @@ -63,13 +63,13 @@ import { Component, Input, HostBinding } from '@angular/core'; - + - + diff --git a/src/framework/theme/components/card/reveal-card/reveal-card.component.ts b/src/framework/theme/components/card/reveal-card/reveal-card.component.ts index 6ddf270c8e..63bbeffa4a 100644 --- a/src/framework/theme/components/card/reveal-card/reveal-card.component.ts +++ b/src/framework/theme/components/card/reveal-card/reveal-card.component.ts @@ -63,7 +63,7 @@ import { Component, Input, HostBinding } from '@angular/core'; - + `, }) diff --git a/src/framework/theme/components/chat/_chat.component.theme.scss b/src/framework/theme/components/chat/_chat.component.theme.scss index cd24556c4f..37a8b1e983 100644 --- a/src/framework/theme/components/chat/_chat.component.theme.scss +++ b/src/framework/theme/components/chat/_chat.component.theme.scss @@ -265,12 +265,17 @@ @include nb-rtl(border-bottom-right-radius, 0); @include nb-rtl(border-top-right-radius, 0); padding: 0 1.5rem; + color: white; &.with-icon { - font-size: 3rem; + font-size: 1.25rem; line-height: 1; padding: 0 1.25rem 0 0.875rem; text-align: center; + + nb-icon { + vertical-align: middle; + } } } diff --git a/src/framework/theme/components/chat/chat-form.component.ts b/src/framework/theme/components/chat/chat-form.component.ts index 1bd2fa850a..24ac312eff 100644 --- a/src/framework/theme/components/chat/chat-form.component.ts +++ b/src/framework/theme/components/chat/chat-form.component.ts @@ -62,7 +62,7 @@ import { DomSanitizer } from '@angular/platform-browser'; - + × @@ -74,7 +74,7 @@ import { DomSanitizer } from '@angular/platform-browser'; placeholder="{{ fileOver ? 'Drop file to send' : 'Type a message' }}" (keyup.enter)="sendMessage()"> - {{ buttonTitle }} + {{ buttonTitle }} `, @@ -101,7 +101,7 @@ export class NbChatFormComponent { * Send button icon, shown if `buttonTitle` is empty * @type {string} */ - @Input() buttonIcon: string = 'paper-plane'; + @Input() buttonIcon: string = 'paper-plane-outline'; /** * 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 b2ae7a60b8..c4e1131500 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'; 1"> - + diff --git a/src/framework/theme/components/icon/_icon.component.theme.scss b/src/framework/theme/components/icon/_icon.component.theme.scss index 659f3f3824..7b7e2a3a1a 100644 --- a/src/framework/theme/components/icon/_icon.component.theme.scss +++ b/src/framework/theme/components/icon/_icon.component.theme.scss @@ -8,6 +8,8 @@ nb-icon { font-size: nb-theme(icon-font-size); line-height: nb-theme(icon-line-height); + width: 1em; + height: 1em; &.primary-icon { color: nb-theme(icon-primary-fg); diff --git a/src/framework/theme/components/icon/icon.module.ts b/src/framework/theme/components/icon/icon.module.ts index cc22d6270c..cc9fcb5138 100644 --- a/src/framework/theme/components/icon/icon.module.ts +++ b/src/framework/theme/components/icon/icon.module.ts @@ -23,9 +23,34 @@ import { NbIconsLibrary } from './icons-library'; }) export class NbIconModule { + private essentialsPackName = 'essentials'; + 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'); + + // in case of consequent calls we don't need to enable `essentials` pack again + if (this.iconsLibrary.getPack(this.essentialsPackName)) { + return; + } + + // tslint:disable + this.iconsLibrary.registerSvgPack(this.essentialsPackName, { + 'chevron-down-outline': '', + 'chevron-up-outline': '', + 'chevron-left-outline': '', + 'chevron-right-outline': '', + 'checkmark-outline': '', + 'paper-plane-outline': '', + 'file-text-outline': '', + 'alert-triangle-outline': '', + 'question-mark-outline': '', + 'email-outline': '', + 'flash-outline': '', + 'search-outline': '', + 'close-outline': '', + 'collapse-outline': '', + 'expand-outline': '', + 'minus-outline': '', + }); + // tslint:enable } } diff --git a/src/framework/theme/components/icon/icons-library.spec.ts b/src/framework/theme/components/icon/icons-library.spec.ts index f43b732f20..053e92bd27 100644 --- a/src/framework/theme/components/icon/icons-library.spec.ts +++ b/src/framework/theme/components/icon/icons-library.spec.ts @@ -74,8 +74,10 @@ describe('icons-library', () => { iconsLibrary.setDefaultPack('super-pack'); + // ts-lint: disable expect(() => iconsLibrary.getSvgIcon('unknown')) - .toThrowError(`Icon 'unknown' is not registered in pack 'super-pack'`); + .toThrowError(`Icon 'unknown' is not registered in pack 'super-pack'. Check icon name or consider switching icon pack.`); + // ts-lint: enable }); it('should throw for no default pack', () => { @@ -99,9 +101,10 @@ describe('icons-library', () => { iconsLibrary.registerFontPack('font-pack'); iconsLibrary.setDefaultPack('super-pack'); - + // ts-lint: disable expect(() => iconsLibrary.getSvgIcon('unknown')) - .toThrowError(`Icon 'unknown' is not registered in pack 'super-pack'`); + .toThrowError(`Icon 'unknown' is not registered in pack 'super-pack'. Check icon name or consider switching icon pack.`); + // ts-lint: enable }); it('should throw for wrong pack when setting default', () => { @@ -138,6 +141,7 @@ describe('icons-library', () => { expect(icon.icon.render()).toEqual(''); expect(icon.icon.getClasses()).toEqual(['font', 'fp-home']); + 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/components/icon/icons-library.ts b/src/framework/theme/components/icon/icons-library.ts index 65ad6e5f25..1ac7d0253b 100644 --- a/src/framework/theme/components/icon/icons-library.ts +++ b/src/framework/theme/components/icon/icons-library.ts @@ -24,7 +24,7 @@ function throwNoDefaultPackError() { } function throwIconNotFoundError(name: string, pack: string) { - throw Error(`Icon '${name}' is not registered in pack '${pack}'`); + throw Error(`Icon '${name}' is not registered in pack '${pack}'. Check icon name or consider switching icon pack.`); } /** @@ -54,6 +54,10 @@ export class NbIconsLibrary { }); } + getPack(name: string) { + return this.packs.get(name); + } + setDefaultPack(name: string) { if (!this.packs.has(name)) { throwPackNotFoundError(name); diff --git a/src/framework/theme/components/menu/menu-item.component.html b/src/framework/theme/components/menu/menu-item.component.html index ff00cec765..f6817c0cd7 100644 --- a/src/framework/theme/components/menu/menu-item.component.html +++ b/src/framework/theme/components/menu/menu-item.component.html @@ -43,7 +43,7 @@ href="#"> {{ menuItem.title }} - + - + @@ -204,7 +204,7 @@ export class NbSearchFieldComponent implements OnChanges, AfterViewInit { styleUrls: ['styles/search.component.scss'], template: ` - + {{ index + 1 }} - + diff --git a/src/framework/theme/components/toastr/_toast.component.theme.scss b/src/framework/theme/components/toastr/_toast.component.theme.scss index b040d96902..247fbfa8f9 100644 --- a/src/framework/theme/components/toastr/_toast.component.theme.scss +++ b/src/framework/theme/components/toastr/_toast.component.theme.scss @@ -12,13 +12,19 @@ border: nb-theme(toastr-border); border-radius: nb-theme(toastr-border-radius); - nb-icon { + .icon-container { @include nb-ltr(margin-right, 1.25rem); @include nb-rtl(margin-left, 1.25rem); - } - - i { border-radius: nb-theme(toastr-icon-radius); + width: 2.5rem; + height: 2.5rem; + display: flex; + justify-content: center; + align-items: center; + + nb-icon { + font-size: 1.5rem; + } } @include nb-except-theme(cosmic) { @@ -39,9 +45,8 @@ border-color: nb-theme(color-success); color: nb-theme(color-success); - nb-icon { + .icon-container { background-color: nb-theme(color-success); - color: nb-theme(color-white); } @@ -49,9 +54,8 @@ @include btn-hero-success-gradient(); color: nb-theme(toastr-color-fg); - nb-icon { + .icon-container { background-color: nb-theme(color-white); - color: nb-theme(color-success); } } @@ -61,9 +65,8 @@ border-color: nb-theme(color-info); color: nb-theme(color-info); - nb-icon { + .icon-container { background-color: nb-theme(color-info); - color: nb-theme(color-white); } @@ -71,9 +74,8 @@ @include btn-hero-info-gradient(); color: nb-theme(toastr-color-fg); - nb-icon { + .icon-container { background-color: nb-theme(color-white); - color: nb-theme(color-info); } } @@ -83,9 +85,8 @@ border-color: nb-theme(color-warning); color: nb-theme(color-warning); - nb-icon { + .icon-container { background-color: nb-theme(color-warning); - color: nb-theme(color-white); } @@ -93,9 +94,8 @@ @include btn-hero-warning-gradient(); color: nb-theme(toastr-color-fg); - nb-icon { + .icon-container { background-color: nb-theme(color-white); - color: nb-theme(color-warning); } } @@ -105,9 +105,8 @@ border-color: nb-theme(color-primary); color: nb-theme(color-primary); - nb-icon { + .icon-container { background-color: nb-theme(color-primary); - color: nb-theme(color-white); } @@ -115,9 +114,8 @@ @include btn-hero-primary-gradient(); color: nb-theme(toastr-color-fg); - nb-icon { + .icon-container { background-color: nb-theme(color-white); - color: nb-theme(color-primary); } } @@ -127,9 +125,8 @@ border-color: nb-theme(color-danger); color: nb-theme(color-danger); - nb-icon { + .icon-container { background-color: nb-theme(color-danger); - color: nb-theme(color-white); } @@ -137,9 +134,8 @@ @include btn-hero-danger-gradient(); color: nb-theme(toastr-color-fg); - nb-icon { + .icon-container { background-color: nb-theme(color-white); - color: nb-theme(color-danger); } } diff --git a/src/framework/theme/components/toastr/toast.component.html b/src/framework/theme/components/toastr/toast.component.html index 3cdb22182d..1fc9b0f202 100644 --- a/src/framework/theme/components/toastr/toast.component.html +++ b/src/framework/theme/components/toastr/toast.component.html @@ -1,4 +1,6 @@ - + + + {{ toast.title }} {{ toast.message }} diff --git a/src/framework/theme/components/toastr/toast.component.ts b/src/framework/theme/components/toastr/toast.component.ts index 86026d1d71..1677ecb0e9 100644 --- a/src/framework/theme/components/toastr/toast.component.ts +++ b/src/framework/theme/components/toastr/toast.component.ts @@ -85,6 +85,10 @@ export class NbToastComponent { return this.toast.config.icon; } + get iconPack(): string { + return this.toast.config.iconPack; + } + @HostListener('click') onClick() { this.destroy.emit(); diff --git a/src/framework/theme/components/toastr/toastr-config.ts b/src/framework/theme/components/toastr/toastr-config.ts index 400e0b8b18..0ad6517e5e 100644 --- a/src/framework/theme/components/toastr/toastr-config.ts +++ b/src/framework/theme/components/toastr/toastr-config.ts @@ -41,18 +41,22 @@ export class NbToastrConfig { * */ hasIcon: boolean = true; /** - * Icon class that can be provided to render custom icon. + * Icon name that can be provided to render custom icon. * */ icon: string = 'email'; + /** + * Icon pack to look for the icon in. + * */ + iconPack: string; /** * Toast status icon-class mapping. * */ protected icons = { - [NbToastStatus.DANGER]: 'danger', - [NbToastStatus.SUCCESS]: 'checkmark-circle', - [NbToastStatus.INFO]: 'help', - [NbToastStatus.WARNING]: 'alert', - [NbToastStatus.PRIMARY]: 'email', + [NbToastStatus.DANGER]: 'flash-outline', + [NbToastStatus.SUCCESS]: 'checkmark-outline', + [NbToastStatus.INFO]: 'question-mark-outline', + [NbToastStatus.WARNING]: 'alert-triangle-outline', + [NbToastStatus.PRIMARY]: 'email-outline', }; constructor(config: Partial) { diff --git a/src/framework/theme/components/tree-grid/_tree-grid.component.theme.scss b/src/framework/theme/components/tree-grid/_tree-grid.component.theme.scss index a3b662c499..0471cb8797 100644 --- a/src/framework/theme/components/tree-grid/_tree-grid.component.theme.scss +++ b/src/framework/theme/components/tree-grid/_tree-grid.component.theme.scss @@ -17,10 +17,10 @@ height: nb-theme(tree-grid-row-min-height); padding: nb-theme(tree-grid-cell-padding); border: $border-width $border-style $border-color; + } - nb-icon { - font-size: 1rem; - } + .nb-tree-grid-header-cell { + line-height: 1.5; } .nb-tree-grid-header-row { @@ -41,9 +41,18 @@ } } - nb-tree-grid-row-toggle .row-toggle-button nb-icon, - nb-sort-icon nb-icon { - color: nb-theme(tree-grid-icon-color); + .nb-tree-grid-header-cell { + button { + vertical-align: middle; + } + } + + nb-tree-grid-row-toggle, nb-sort-icon { + nb-icon { + font-size: inherit; + vertical-align: middle; + color: nb-theme(tree-grid-icon-color); + } } @include nb-tree-grid-sort-header-theme(); diff --git a/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts b/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts index 30bc69ea88..0cfa91cb02 100644 --- a/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts +++ b/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts @@ -14,7 +14,7 @@ import { NbTreeGridCellDirective } from './tree-grid-cell.component'; selector: 'nb-tree-grid-row-toggle', template: ` - + `, styles: [` diff --git a/src/framework/theme/components/tree-grid/tree-grid-sort.component.ts b/src/framework/theme/components/tree-grid/tree-grid-sort.component.ts index 046bcf72f1..62b19febdf 100644 --- a/src/framework/theme/components/tree-grid/tree-grid-sort.component.ts +++ b/src/framework/theme/components/tree-grid/tree-grid-sort.component.ts @@ -82,8 +82,8 @@ export class NbSortHeaderIconDirective {} selector: 'nb-sort-icon', template: ` - - + + `, }) diff --git a/src/framework/theme/components/window/window.component.ts b/src/framework/theme/components/window/window.component.ts index afeefdc26a..ad08c84183 100644 --- a/src/framework/theme/components/window/window.component.ts +++ b/src/framework/theme/components/window/window.component.ts @@ -33,16 +33,16 @@ import { NbWindowRef } from './window-ref'; - + - + - + - + diff --git a/src/framework/theme/components/window/window.module.ts b/src/framework/theme/components/window/window.module.ts index 505cb45c33..117e4a27a7 100644 --- a/src/framework/theme/components/window/window.module.ts +++ b/src/framework/theme/components/window/window.module.ts @@ -2,13 +2,14 @@ import { ModuleWithProviders, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NbOverlayModule } from '../cdk/overlay'; import { NbCardModule } from '../card/card.module'; +import { NbIconModule } from '../icon/icon.module'; import { NbWindowService } from './window.service'; import { NbWindowsContainerComponent } from './windows-container.component'; import { NbWindowComponent } from './window.component'; import { NB_WINDOW_CONFIG, NbWindowConfig } from './window.options'; @NgModule({ - imports: [CommonModule, NbOverlayModule, NbCardModule], + imports: [CommonModule, NbOverlayModule, NbCardModule, NbIconModule], declarations: [ NbWindowsContainerComponent, NbWindowComponent, diff --git a/src/framework/theme/styles/themes/_default.scss b/src/framework/theme/styles/themes/_default.scss index 59537acae1..762d166ae1 100644 --- a/src/framework/theme/styles/themes/_default.scss +++ b/src/framework/theme/styles/themes/_default.scss @@ -190,7 +190,7 @@ $theme: ( menu-group-padding: 1rem 1.25rem, menu-item-padding: 0.675rem 0.75rem, menu-item-separator: separator, - menu-icon-font-size: 2.5rem, + menu-icon-font-size: 1.5rem, menu-icon-margin: 0 0.25rem 0, menu-icon-color: color-fg, menu-icon-active-color: color-fg-heading, @@ -567,7 +567,7 @@ $theme: ( stepper-accent-color: color-primary, stepper-completed-fg: color-white, stepper-fg: color-fg, - stepper-completed-icon-size: 1.5rem, + stepper-completed-icon-size: 1.25rem, stepper-completed-icon-weight: font-weight-ultra-bold, stepper-step-padding: padding, @@ -697,7 +697,7 @@ $theme: ( tree-grid-sort-header-button-color: color-fg-text, tree-grid-icon-color: color-fg-text, - icon-font-size: 1.5rem, + icon-font-size: 1.25rem, icon-width: icon-font-size, icon-height: icon-font-size, icon-primary-fg: color-primary, diff --git a/src/playground/with-layout/icon/icon-showcase.component.ts b/src/playground/with-layout/icon/icon-showcase.component.ts index fde52a932e..92d951fead 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.ts +++ b/src/playground/with-layout/icon/icon-showcase.component.ts @@ -18,6 +18,8 @@ export class IconShowcaseComponent { // package release setup // update all icon components // migration strategy (for nebular icons, and when eva becomes default) + // packages smoke + // check icons in all playground components // do examples: // icon in button // icon prefix @@ -26,5 +28,6 @@ export class IconShowcaseComponent { // 3. custom font pack // 4. custom svg pack // 5 custom svg icon rendering + // TODO: STATUS ICONS } } From 8d99416568ab5f660ee5891ff677dbe591f64868 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Mon, 25 Mar 2019 19:31:37 +0300 Subject: [PATCH 21/33] feat(playground): register eva and replace icons in examples --- src/playground/playground.module.ts | 4 +- .../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 +- .../with-layout/chat/bot-replies.ts | 8 +-- .../chat-conversation-showcase.component.ts | 2 +- .../with-layout/chat/chat-drop.component.ts | 2 +- .../chat-message-types-showcase.component.ts | 4 +- .../chat/chat-showcase.component.ts | 2 +- src/playground/with-layout/chat/messages.ts | 2 +- .../icon/icon-showcase.component.html | 2 +- .../icon/icon-showcase.component.ts | 6 +-- .../menu/menu-link-params.component.ts | 2 +- .../with-layout/menu/menu-service-items.ts | 16 +++--- .../menu/menu-service.component.ts | 2 +- .../menu/menu-showcase.component.ts | 8 +-- .../progress-bar-interactive.component.html | 4 +- .../tabset/tabset-icon.component.html | 18 +++---- .../toastr/toastr-icon.component.ts | 4 +- .../tooltip/tooltip-with-icon.component.html | 4 +- .../tree-grid/components/fs-icon.component.ts | 2 +- .../context-menu-test.component.ts | 4 +- .../layout/layout-subheader.component.html | 6 +-- .../menu/menu-test.component.ts | 22 ++++---- 26 files changed, 110 insertions(+), 108 deletions(-) diff --git a/src/playground/playground.module.ts b/src/playground/playground.module.ts index 7ace3e26ec..86955dfbbb 100644 --- a/src/playground/playground.module.ts +++ b/src/playground/playground.module.ts @@ -5,9 +5,11 @@ */ import { NgModule } from '@angular/core'; +import { NbEvaIconsModule } from '@nebular/eva-icons'; + import { PlaygroundRoutingModule } from './playground-routing.module'; @NgModule({ - imports: [ PlaygroundRoutingModule ], + imports: [ PlaygroundRoutingModule, NbEvaIconsModule ], }) export class PlaygroundModule {} diff --git a/src/playground/with-layout/action/action-badge.component.html b/src/playground/with-layout/action/action-badge.component.html index 0fcb6fa15b..c18b10996a 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 7759f656ee..71a2a46694 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 40067b6e1d..f010bd24f6 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 ad079dca99..1812d60011 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="email"> + icon="search-outline"> + icon="search-outline"> + icon="search-outline"> + icon="search-outline"> Badge diff --git a/src/playground/with-layout/action/action-width.component.html b/src/playground/with-layout/action/action-width.component.html index 4aad1ac602..efefa43925 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 @@ - - + + diff --git a/src/playground/with-layout/chat/bot-replies.ts b/src/playground/with-layout/chat/bot-replies.ts index 7b94d45910..ac2859d0be 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: 'compose', + icon: 'file-text-outline', }, { url: '', @@ -111,7 +111,7 @@ export const botReplies = [ type: 'image/jpeg', }, ], - icon: 'compose', + icon: 'file-text-outline', user: { name: 'Bot', avatar: botAvatar, @@ -130,10 +130,10 @@ export const botReplies = [ files: [ { url: fileLink, - icon: 'compose', + icon: 'file-text-outline', }, ], - icon: 'compose', + icon: 'file-text-outline', 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 ae27e5ef7e..9f26e592a1 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: 'compose', + icon: 'file-text-outline', }; }); diff --git a/src/playground/with-layout/chat/chat-drop.component.ts b/src/playground/with-layout/chat/chat-drop.component.ts index eb18f8b6da..8559355909 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: 'compose', + icon: 'file-text-outline', }; }); 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 f108ec6268..d6b6d9e9d8 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: 'compose' } ]" + [files]="[ { url: 'http://google.com', icon: 'file-text-outline' } ]" [avatar]="'https://i.gifer.com/no.gif'"> - + diff --git a/src/playground/with-layout/icon/icon-showcase.component.ts b/src/playground/with-layout/icon/icon-showcase.component.ts index 92d951fead..6b157a7ba9 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.ts +++ b/src/playground/with-layout/icon/icon-showcase.component.ts @@ -15,11 +15,11 @@ export class IconShowcaseComponent { constructor() { - // package release setup - // update all icon components // migration strategy (for nebular icons, and when eva becomes default) + // - essential icons + // - nebular eva icons + // - how to use nebular font // packages smoke - // check icons in all playground components // do examples: // icon in button // icon prefix diff --git a/src/playground/with-layout/menu/menu-link-params.component.ts b/src/playground/with-layout/menu/menu-link-params.component.ts index 51d41780ba..3502d53335 100644 --- a/src/playground/with-layout/menu/menu-link-params.component.ts +++ b/src/playground/with-layout/menu/menu-link-params.component.ts @@ -41,7 +41,7 @@ export class MenuLinkParamsComponent { { title: 'Menu item with icon', link: '/example/menu/menu-link-params.component', - icon: 'nb-search', + icon: 'search-outline', }, { title: 'Hidden menu item', diff --git a/src/playground/with-layout/menu/menu-service-items.ts b/src/playground/with-layout/menu/menu-service-items.ts index cb6faa093b..63948c6647 100644 --- a/src/playground/with-layout/menu/menu-service-items.ts +++ b/src/playground/with-layout/menu/menu-service-items.ts @@ -2,43 +2,43 @@ export const MENU_ITEMS = [ { title: 'Home', link: '/example/menu/menu-service.component', - icon: 'nb-home', + icon: 'home-outline', home: true, }, { title: 'User account', link: '/example/menu/menu-service.component/2', - icon: 'nb-person', + icon: 'person-outline', }, { title: 'Shop', - icon: 'nb-e-commerce', + icon: 'shopping-cart-outline', expanded: true, children: [ { title: 'Services', link: '/example/menu/menu-service.component/3/1', - icon: 'nb-gear', + icon: 'settings-outline', }, { title: 'Hardware', link: '/example/menu/menu-service.component/3/2', - icon: 'nb-lightbulb', + icon: 'bulb-outline', }, { title: 'Software', - icon: 'nb-grid-a-outline', + icon: 'grid-outline', expanded: true, children: [ { title: 'Open Source', link: '/example/menu/menu-service.component/3/3/1', - icon: 'nb-grid-b', + icon: 'grid-outline', }, { title: 'Commercial', link: '/example/menu/menu-service.component/3/3/2', - icon: 'nb-grid-b-outline', + icon: 'grid-outline', queryParams: {param: 2}, fragment: 'fragment', }, diff --git a/src/playground/with-layout/menu/menu-service.component.ts b/src/playground/with-layout/menu/menu-service.component.ts index 076eab9e28..44434ec716 100644 --- a/src/playground/with-layout/menu/menu-service.component.ts +++ b/src/playground/with-layout/menu/menu-service.component.ts @@ -43,7 +43,7 @@ export class MenuServiceComponent implements OnDestroy { this.menuService.addItems([{ title: '@nebular/theme', target: '_blank', - icon: 'nb-plus', + icon: 'plus-outline', url: 'https://github.com/akveo/ngx-admin', }], 'menu'); } diff --git a/src/playground/with-layout/menu/menu-showcase.component.ts b/src/playground/with-layout/menu/menu-showcase.component.ts index 3adebcbe75..20c9a4c356 100644 --- a/src/playground/with-layout/menu/menu-showcase.component.ts +++ b/src/playground/with-layout/menu/menu-showcase.component.ts @@ -16,22 +16,22 @@ export class MenuShowcaseComponent { items = [ { title: 'Profile', - icon: 'person', + icon: 'person-outline', link: [], }, { title: 'Change Password', - icon: 'locked', + icon: 'lock-outline', link: [], }, { title: 'Privacy Policy', - icon: 'checkmark', + icon: 'checkmark-outline', link: [], }, { title: 'Logout', - icon: 'arrow-thin-left', + icon: 'unlock-outline', link: [], }, ]; diff --git a/src/playground/with-layout/progress-bar/progress-bar-interactive.component.html b/src/playground/with-layout/progress-bar/progress-bar-interactive.component.html index f8202f279b..7482b19370 100644 --- a/src/playground/with-layout/progress-bar/progress-bar-interactive.component.html +++ b/src/playground/with-layout/progress-bar/progress-bar-interactive.component.html @@ -2,11 +2,11 @@ - + - + diff --git a/src/playground/with-layout/tabset/tabset-icon.component.html b/src/playground/with-layout/tabset/tabset-icon.component.html index 19328e5609..38bb6703c5 100644 --- a/src/playground/with-layout/tabset/tabset-icon.component.html +++ b/src/playground/with-layout/tabset/tabset-icon.component.html @@ -2,13 +2,13 @@ - + List of users. - + List of orders. - + List of transactions. @@ -20,13 +20,13 @@ - + List of users. - + List of orders. - + List of transactions. @@ -38,13 +38,13 @@ - + List of users. - + List of orders. - + List of transactions. diff --git a/src/playground/with-layout/toastr/toastr-icon.component.ts b/src/playground/with-layout/toastr/toastr-icon.component.ts index bfbe229116..c887c34e14 100644 --- a/src/playground/with-layout/toastr/toastr-icon.component.ts +++ b/src/playground/with-layout/toastr/toastr-icon.component.ts @@ -6,7 +6,7 @@ import { NbToastrService } from '@nebular/theme'; template: ` With icon Without icon - Custom icon + Custom icon `, styles: [ ` @@ -32,6 +32,6 @@ export class ToastrIconComponent { } showToast(icon) { - this.toastrService.show('Message', `Toast: ${++this.index}`, { icon }); + this.toastrService.show('Message', `Toast: ${++this.index}`, { icon, iconPack: 'eva' }); } } diff --git a/src/playground/with-layout/tooltip/tooltip-with-icon.component.html b/src/playground/with-layout/tooltip/tooltip-with-icon.component.html index 48e4f7f761..a2701aeeac 100644 --- a/src/playground/with-layout/tooltip/tooltip-with-icon.component.html +++ b/src/playground/with-layout/tooltip/tooltip-with-icon.component.html @@ -1,2 +1,2 @@ -Show Tooltip -Show Tooltip +Show Tooltip +Show Tooltip diff --git a/src/playground/with-layout/tree-grid/components/fs-icon.component.ts b/src/playground/with-layout/tree-grid/components/fs-icon.component.ts index 844713486e..1881316598 100644 --- a/src/playground/with-layout/tree-grid/components/fs-icon.component.ts +++ b/src/playground/with-layout/tree-grid/components/fs-icon.component.ts @@ -6,7 +6,7 @@ import { Component, Input } from '@angular/core'; - + `, }) diff --git a/src/playground/without-layout/context-menu/context-menu-test.component.ts b/src/playground/without-layout/context-menu/context-menu-test.component.ts index 75a876e79a..8d04488da1 100644 --- a/src/playground/without-layout/context-menu/context-menu-test.component.ts +++ b/src/playground/without-layout/context-menu/context-menu-test.component.ts @@ -33,7 +33,7 @@ export class ContextMenuTestComponent { ]; itemsWithIcons = [ - { title: 'Profile', link: '/user', icon: 'nb-compose' }, - { title: 'Logout', link: '/popover', icon: 'nb-gear' }, + { title: 'Profile', link: '/user', icon: 'person-outline' }, + { title: 'Logout', link: '/popover', icon: 'settings-outline' }, ]; } diff --git a/src/playground/without-layout/layout/layout-subheader.component.html b/src/playground/without-layout/layout/layout-subheader.component.html index f20a847973..2a175a46c1 100644 --- a/src/playground/without-layout/layout/layout-subheader.component.html +++ b/src/playground/without-layout/layout/layout-subheader.component.html @@ -5,9 +5,9 @@ - - - + + + diff --git a/src/playground/without-layout/menu/menu-test.component.ts b/src/playground/without-layout/menu/menu-test.component.ts index 3ae8e4307e..73d6642a3c 100644 --- a/src/playground/without-layout/menu/menu-test.component.ts +++ b/src/playground/without-layout/menu/menu-test.component.ts @@ -46,23 +46,23 @@ export class MenuTestComponent implements OnInit, OnDestroy { { title: 'Menu Items', group: true, - icon: 'nb-keypad', + icon: 'home-outline', }, { title: 'Menu #1', link: '/menu/menu-test.component/1', - icon: 'nb-keypad', + icon: 'home-outline', queryParams: { param: 1 }, fragment: '#fragment', }, { title: 'Menu #2', link: '/menu/menu-test.component/2', - icon: 'nb-keypad', + icon: 'home-outline', }, { title: 'Menu #3', - icon: 'nb-keypad', + icon: 'home-outline', children: [ { title: 'Menu #3.1', @@ -100,19 +100,19 @@ export class MenuTestComponent implements OnInit, OnDestroy { { title: 'Menu Items', group: true, - icon: 'nb-keypad', + icon: 'home-outline', }, { title: 'Menu #1', link: '/menu/menu-test.component/1', - icon: 'nb-keypad', + icon: 'home-outline', queryParams: { param: 1 }, fragment: '#fragment', }, { title: 'Menu #2', link: '/menu/menu-test.component/2', - icon: 'nb-keypad', + icon: 'home-outline', }, ]; secondMenuItems = [ @@ -123,19 +123,19 @@ export class MenuTestComponent implements OnInit, OnDestroy { { title: 'Menu #1', link: '/menu/menu-test.component/1', - icon: 'nb-keypad', + icon: 'home-outline', pathMatch: 'partial', }, { title: 'Menu #12 + fragment', link: '/menu/menu-test.component/12', fragment: 'fragment', - icon: 'nb-keypad', + icon: 'home-outline', }, { title: 'Menu #3', link: '/menu/menu-test.component/3', - icon: 'nb-keypad', + icon: 'home-outline', }, ]; thirdMenuItems = [ @@ -187,7 +187,7 @@ export class MenuTestComponent implements OnInit, OnDestroy { [ { title: 'Menu #3', - icon: 'nb-keypad', + icon: 'home-outline', children: [ { title: 'Menu #3.1', From b7e97f37d35e6216cbcaa340c0562ccfc0268dd2 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Mon, 25 Mar 2019 19:51:12 +0300 Subject: [PATCH 22/33] feat(icon): icon color example --- src/app/playground-components.ts | 6 ++++++ .../theme/components/icon/icons-library.spec.ts | 6 ++---- .../tree-grid/tree-grid-row-toggle.component.ts | 5 ++++- .../with-layout/icon/icon-colors.component.html | 9 +++++++++ .../with-layout/icon/icon-colors.component.ts | 15 +++++++++++++++ .../with-layout/icon/icon-routing.module.ts | 5 +++++ .../with-layout/icon/icon-showcase.component.html | 2 +- src/playground/with-layout/icon/icon.module.ts | 2 ++ 8 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 src/playground/with-layout/icon/icon-colors.component.html create mode 100644 src/playground/with-layout/icon/icon-colors.component.ts diff --git a/src/app/playground-components.ts b/src/app/playground-components.ts index f2854d482c..34995e42fc 100644 --- a/src/app/playground-components.ts +++ b/src/app/playground-components.ts @@ -1318,6 +1318,12 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [ component: 'IconShowcaseComponent', name: 'Icon Showcase', }, + { + path: 'icon-colors.component', + link: '/icon/icon-colors.component', + component: 'IconColorsComponent', + name: 'Icon Colors', + }, ], }, { diff --git a/src/framework/theme/components/icon/icons-library.spec.ts b/src/framework/theme/components/icon/icons-library.spec.ts index 053e92bd27..131bc090c0 100644 --- a/src/framework/theme/components/icon/icons-library.spec.ts +++ b/src/framework/theme/components/icon/icons-library.spec.ts @@ -74,10 +74,9 @@ describe('icons-library', () => { iconsLibrary.setDefaultPack('super-pack'); - // ts-lint: disable expect(() => iconsLibrary.getSvgIcon('unknown')) + // tslint:disable-next-line:max-line-length .toThrowError(`Icon 'unknown' is not registered in pack 'super-pack'. Check icon name or consider switching icon pack.`); - // ts-lint: enable }); it('should throw for no default pack', () => { @@ -101,10 +100,9 @@ describe('icons-library', () => { iconsLibrary.registerFontPack('font-pack'); iconsLibrary.setDefaultPack('super-pack'); - // ts-lint: disable expect(() => iconsLibrary.getSvgIcon('unknown')) + // tslint:disable-next-line:max-line-length .toThrowError(`Icon 'unknown' is not registered in pack 'super-pack'. Check icon name or consider switching icon pack.`); - // ts-lint: enable }); it('should throw for wrong pack when setting default', () => { diff --git a/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts b/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts index 0cfa91cb02..187bebddf1 100644 --- a/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts +++ b/src/framework/theme/components/tree-grid/tree-grid-row-toggle.component.ts @@ -14,7 +14,10 @@ import { NbTreeGridCellDirective } from './tree-grid-cell.component'; selector: 'nb-tree-grid-row-toggle', template: ` - + + `, styles: [` diff --git a/src/playground/with-layout/icon/icon-colors.component.html b/src/playground/with-layout/icon/icon-colors.component.html new file mode 100644 index 0000000000..aa3e78839b --- /dev/null +++ b/src/playground/with-layout/icon/icon-colors.component.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/playground/with-layout/icon/icon-colors.component.ts b/src/playground/with-layout/icon/icon-colors.component.ts new file mode 100644 index 0000000000..f5825d1b58 --- /dev/null +++ b/src/playground/with-layout/icon/icon-colors.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-colors', + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './icon-colors.component.html', +}) +export class IconColorsComponent { +} diff --git a/src/playground/with-layout/icon/icon-routing.module.ts b/src/playground/with-layout/icon/icon-routing.module.ts index 2ab0a92831..4f4541cdf3 100644 --- a/src/playground/with-layout/icon/icon-routing.module.ts +++ b/src/playground/with-layout/icon/icon-routing.module.ts @@ -8,12 +8,17 @@ import { NgModule } from '@angular/core'; import { RouterModule, Route } from '@angular/router'; import { IconShowcaseComponent } from './icon-showcase.component'; +import { IconColorsComponent } from './icon-colors.component'; const routes: Route[] = [ { path: 'icon-showcase.component', component: IconShowcaseComponent, }, + { + path: 'icon-colors.component', + component: IconColorsComponent, + }, ]; @NgModule({ diff --git a/src/playground/with-layout/icon/icon-showcase.component.html b/src/playground/with-layout/icon/icon-showcase.component.html index eec0b60038..e6723fc74d 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.html +++ b/src/playground/with-layout/icon/icon-showcase.component.html @@ -1,5 +1,5 @@ - + diff --git a/src/playground/with-layout/icon/icon.module.ts b/src/playground/with-layout/icon/icon.module.ts index b1451af05c..42f4ea29bb 100644 --- a/src/playground/with-layout/icon/icon.module.ts +++ b/src/playground/with-layout/icon/icon.module.ts @@ -10,10 +10,12 @@ import { NbIconModule, NbButtonModule, NbCardModule } from '@nebular/theme'; import { IconRoutingModule } from './icon-routing.module'; import { IconShowcaseComponent } from './icon-showcase.component'; +import { IconColorsComponent } from './icon-colors.component'; @NgModule({ declarations: [ IconShowcaseComponent, + IconColorsComponent, ], imports: [ CommonModule, From 3b6eef126afe3a8f5425b143b9906d50ed408b95 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Tue, 26 Mar 2019 15:43:04 +0300 Subject: [PATCH 23/33] feat(button): add button icon --- docs/app/@theme/styles/styles.scss | 1 + docs/tsconfig.app.json | 3 ++- src/app/playground-components.ts | 6 +++++ .../components/button/button.component.scss | 16 ++++++++++++++ .../components/button/button.component.ts | 22 +++++++++++++++++++ .../button/button-icon.component.html | 8 +++++++ .../button/button-icon.component.ts | 21 ++++++++++++++++++ .../button/button-routing.module.ts | 5 +++++ .../with-layout/button/button.module.ts | 6 +++-- 9 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/playground/with-layout/button/button-icon.component.html create mode 100644 src/playground/with-layout/button/button-icon.component.ts diff --git a/docs/app/@theme/styles/styles.scss b/docs/app/@theme/styles/styles.scss index 5fe412de0e..92fc1d64a6 100644 --- a/docs/app/@theme/styles/styles.scss +++ b/docs/app/@theme/styles/styles.scss @@ -16,6 +16,7 @@ @include nb-actions-theme(); @include nb-search-theme(); @include nb-bootstrap-global(); + @include nb-icon-theme(); @include nb-typography(); diff --git a/docs/tsconfig.app.json b/docs/tsconfig.app.json index 52d70edd56..289ccf8992 100644 --- a/docs/tsconfig.app.json +++ b/docs/tsconfig.app.json @@ -19,7 +19,8 @@ "@nebular/theme": ["../src/framework/theme"], "@nebular/theme/*": ["../src/framework/theme/*"], "@nebular/auth": ["../src/framework/auth"], - "@nebular/security": ["../src/framework/security"] + "@nebular/security": ["../src/framework/security"], + "@nebular/eva-icons": ["../src/framework/eva-icons"] } }, "exclude": [ diff --git a/src/app/playground-components.ts b/src/app/playground-components.ts index 34995e42fc..49128d6b99 100644 --- a/src/app/playground-components.ts +++ b/src/app/playground-components.ts @@ -174,6 +174,12 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [ component: 'ButtonTypesComponent', name: 'Button Types', }, + { + path: 'button-icon.component', + link: '/button/button-icon.component', + component: 'ButtonIconComponent', + name: 'Button Icon', + }, ], }, { diff --git a/src/framework/theme/components/button/button.component.scss b/src/framework/theme/components/button/button.component.scss index cbbae4913f..ab0da93ae7 100644 --- a/src/framework/theme/components/button/button.component.scss +++ b/src/framework/theme/components/button/button.component.scss @@ -4,6 +4,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ +@import '../../styles/core/mixins'; + :host { text-transform: uppercase; letter-spacing: 0.4px; @@ -26,4 +28,18 @@ &.btn-full-width { width: 100%; } + + ::ng-deep nb-icon { + vertical-align: top; + } + + &.icon-left:not(.icon-right) ::ng-deep nb-icon { + @include nb-ltr(margin-right, 0.75rem); + @include nb-rtl(margin-left, 0.75rem); + } + + &.icon-right:not(.icon-left) ::ng-deep nb-icon { + @include nb-ltr(margin-left, 0.75rem); + @include nb-rtl(margin-right, 0.75rem); + } } diff --git a/src/framework/theme/components/button/button.component.ts b/src/framework/theme/components/button/button.component.ts index b4a2ffb98a..90965b1b7d 100644 --- a/src/framework/theme/components/button/button.component.ts +++ b/src/framework/theme/components/button/button.component.ts @@ -55,6 +55,9 @@ import { convertToBoolProperty } from '../helpers'; * Button can be made `fullWidth`: * @stacked-example(Full Width Button, button/button-full-width.component.html) * + * Icon can be placed inside of a button as a child element: + * @stacked-example(Icon Button, button/button-icon.component.html) + * * @styles * * btn-fg: @@ -209,6 +212,20 @@ export class NbButtonComponent { return this.disabled ? '-1' : '0'; } + @HostBinding('class.icon-left') + get iconLeft(): boolean { + const el = this.hostElement.nativeElement; + const icon = this.iconElement; + return !!(icon && el.firstChild === icon); + } + + @HostBinding('class.icon-right') + get iconRight(): boolean { + const el = this.hostElement.nativeElement; + const icon = this.iconElement; + return !!(icon && el.lastChild === icon); + } + @HostBinding('class.btn-full-width') fullWidth = false; @@ -241,6 +258,11 @@ export class NbButtonComponent { this.shape = val; } + private get iconElement() { + const el = this.hostElement.nativeElement; + return el.querySelector('nb-icon'); + } + /** * Adds `hero` styles * @param {boolean} val diff --git a/src/playground/with-layout/button/button-icon.component.html b/src/playground/with-layout/button/button-icon.component.html new file mode 100644 index 0000000000..75e1904690 --- /dev/null +++ b/src/playground/with-layout/button/button-icon.component.html @@ -0,0 +1,8 @@ + + Button with Icon + + Primary + Success + + + diff --git a/src/playground/with-layout/button/button-icon.component.ts b/src/playground/with-layout/button/button-icon.component.ts new file mode 100644 index 0000000000..e4c133cc5d --- /dev/null +++ b/src/playground/with-layout/button/button-icon.component.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 { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + selector: 'nb-button-icon', + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './button-icon.component.html', + styles: [` + [nbButton] { + margin-right: 0.75rem; + margin-bottom: 1rem; + } + `], +}) +export class ButtonIconComponent { +} diff --git a/src/playground/with-layout/button/button-routing.module.ts b/src/playground/with-layout/button/button-routing.module.ts index 5c566e70df..055109f680 100644 --- a/src/playground/with-layout/button/button-routing.module.ts +++ b/src/playground/with-layout/button/button-routing.module.ts @@ -14,6 +14,7 @@ import { ButtonShapesComponent } from './button-shapes.component'; import { ButtonShowcaseComponent } from './button-showcase.component'; import { ButtonSizesComponent } from './button-sizes.component'; import { ButtonTypesComponent } from './button-types.component'; +import { ButtonIconComponent } from './button-icon.component'; const routes: Route[] = [ { @@ -48,6 +49,10 @@ const routes: Route[] = [ path: 'button-types.component', component: ButtonTypesComponent, }, + { + path: 'button-icon.component', + component: ButtonIconComponent, + }, ]; @NgModule({ diff --git a/src/playground/with-layout/button/button.module.ts b/src/playground/with-layout/button/button.module.ts index 99dc52677f..ecdf850577 100644 --- a/src/playground/with-layout/button/button.module.ts +++ b/src/playground/with-layout/button/button.module.ts @@ -5,7 +5,7 @@ */ import { NgModule } from '@angular/core'; -import { NbButtonModule, NbCardModule } from '@nebular/theme'; +import { NbButtonModule, NbCardModule, NbIconModule } from '@nebular/theme'; import { ButtonRoutingModule } from './button-routing.module'; import { ButtonColorsComponent } from './button-colors.component'; import { ButtonFullWidthComponent } from './button-full-width.component'; @@ -15,6 +15,7 @@ import { ButtonShapesComponent } from './button-shapes.component'; import { ButtonShowcaseComponent } from './button-showcase.component'; import { ButtonSizesComponent } from './button-sizes.component'; import { ButtonTypesComponent } from './button-types.component'; +import { ButtonIconComponent } from './button-icon.component'; @NgModule({ declarations: [ @@ -26,7 +27,8 @@ import { ButtonTypesComponent } from './button-types.component'; ButtonShowcaseComponent, ButtonSizesComponent, ButtonTypesComponent, + ButtonIconComponent, ], - imports: [ NbCardModule, NbButtonModule, ButtonRoutingModule ], + imports: [ NbCardModule, NbButtonModule, NbIconModule, ButtonRoutingModule ], }) export class ButtonModule {} From 1b5fbec6e46800ae4d4d2d8501692b541279b52a Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Tue, 26 Mar 2019 18:44:56 +0300 Subject: [PATCH 24/33] feat(icon): add docs --- src/framework/eva-icons/eva-icons.module.ts | 4 +- .../{icons-library.ts => icon-libraries.ts} | 44 ++++++- .../components/icon/icon.component.spec.ts | 8 +- .../theme/components/icon/icon.component.ts | 115 ++++++++++-------- .../theme/components/icon/icon.module.ts | 4 +- ...ibrary.spec.ts => icons-libraries.spec.ts} | 8 +- src/framework/theme/index.ts | 2 +- .../icon/icon-showcase.component.html | 1 + .../icon/icon-showcase.component.ts | 5 + 9 files changed, 124 insertions(+), 67 deletions(-) rename src/framework/theme/components/icon/{icons-library.ts => icon-libraries.ts} (81%) rename src/framework/theme/components/icon/{icons-library.spec.ts => icons-libraries.spec.ts} (96%) diff --git a/src/framework/eva-icons/eva-icons.module.ts b/src/framework/eva-icons/eva-icons.module.ts index d10aa545ac..0fdd3cae9e 100644 --- a/src/framework/eva-icons/eva-icons.module.ts +++ b/src/framework/eva-icons/eva-icons.module.ts @@ -5,7 +5,7 @@ */ import { NgModule } from '@angular/core'; -import { NbIconsLibrary, NbSvgIcon, NbIconPackParams, NbIcons } from '@nebular/theme'; +import { NbIconLibraries, NbSvgIcon, NbIconPackParams, NbIcons } from '@nebular/theme'; import { icons } from 'eva-icons'; interface NbOriginalEvaIcon { @@ -44,7 +44,7 @@ export class NbEvaIconsModule { private NAME = 'eva'; - constructor(iconLibrary: NbIconsLibrary) { + constructor(iconLibrary: NbIconLibraries) { iconLibrary.registerSvgPack(this.NAME, this.createIcons()); iconLibrary.setDefaultPack(this.NAME); } diff --git a/src/framework/theme/components/icon/icons-library.ts b/src/framework/theme/components/icon/icon-libraries.ts similarity index 81% rename from src/framework/theme/components/icon/icons-library.ts rename to src/framework/theme/components/icon/icon-libraries.ts index 1ac7d0253b..6213b0a291 100644 --- a/src/framework/theme/components/icon/icons-library.ts +++ b/src/framework/theme/components/icon/icon-libraries.ts @@ -28,14 +28,20 @@ function throwIconNotFoundError(name: string, pack: string) { } /** - * NbIconsLibrary + * This service allows to register multiple icon packs to use them later within `` component. */ @Injectable({providedIn: 'root'}) -export class NbIconsLibrary { +export class NbIconLibraries { protected packs: Map = new Map(); protected defaultPack: NbIconPack; + /** + * Registers new Svg icon pack + * @param {string} name + * @param {NbIcon} icons + * @param {NbIconPackParams} params + */ registerSvgPack(name: string, icons: NbIcons, params: NbIconPackParams = { packClass: '' }) { this.packs.set(name, { name, @@ -45,6 +51,11 @@ export class NbIconsLibrary { }); } + /** + * Registers new font pack + * @param {string} name + * @param {NbIconPackParams} params + */ registerFontPack(name: string, params: NbIconPackParams = { packClass: '' }) { this.packs.set(name, { name, @@ -54,10 +65,18 @@ export class NbIconsLibrary { }); } + /** + * Returns pack by name + * @param {string} name + */ getPack(name: string) { return this.packs.get(name); } + /** + * Sets pack as a default + * @param {string} name + */ setDefaultPack(name: string) { if (!this.packs.has(name)) { throwPackNotFoundError(name); @@ -66,6 +85,13 @@ export class NbIconsLibrary { this.defaultPack = this.packs.get(name); } + /** + * Returns Svg icon + * @param {string} name + * @param {string} pack + * + * @returns NbIconDefinition + */ getSvgIcon(name: string, pack?: string): NbIconDefinition { const iconsPack = this.getPackOrDefault(pack); @@ -84,6 +110,13 @@ export class NbIconsLibrary { }; } + /** + * Returns Font icon + * @param {string} name + * @param {string} pack + * + * @returns NbIconDefinition + */ getFontIcon(name: string, pack?: string): NbIconDefinition { const iconsPack = this.getPackOrDefault(pack); @@ -101,6 +134,13 @@ export class NbIconsLibrary { }; } + /** + * Returns an icon + * @param {string} name + * @param {string} pack + * + * @returns NbIconDefinition + */ getIcon(name: string, pack?: string) { const iconsPack = this.getPackOrDefault(pack); diff --git a/src/framework/theme/components/icon/icon.component.spec.ts b/src/framework/theme/components/icon/icon.component.spec.ts index 551c5bdf5c..e6a38b9449 100644 --- a/src/framework/theme/components/icon/icon.component.spec.ts +++ b/src/framework/theme/components/icon/icon.component.spec.ts @@ -8,7 +8,7 @@ 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'; +import { NbIconLibraries } from './icon-libraries'; @Component({ @@ -27,18 +27,18 @@ describe('Component: NbIcon', () => { let iconTestComponent: IconTestComponent; let fixture: ComponentFixture; let iconElement: ElementRef; - let iconsLibrary: NbIconsLibrary; + let iconsLibrary: NbIconLibraries; beforeEach(() => { const bed = TestBed.configureTestingModule({ imports: [ NbIconModule ], - providers: [ NbIconsLibrary ], + providers: [ NbIconLibraries ], declarations: [ IconTestComponent ], }); fixture = bed.createComponent(IconTestComponent); - iconsLibrary = bed.get(NbIconsLibrary); + iconsLibrary = bed.get(NbIconLibraries); iconsLibrary .registerSvgPack('svg-pack', { home: '' }, { packClass: 'custom-pack' }); diff --git a/src/framework/theme/components/icon/icon.component.ts b/src/framework/theme/components/icon/icon.component.ts index 6dff8904a9..e39e6e0276 100644 --- a/src/framework/theme/components/icon/icon.component.ts +++ b/src/framework/theme/components/icon/icon.component.ts @@ -17,83 +17,82 @@ import { } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; -import { NbIconsLibrary } from './icons-library'; +import { NbIconLibraries } from './icon-libraries'; /** - * Icon component. + * Icon component. Allows to render both `svg` and `font` icons. + * Starting from Nebular 4.0 uses [Eva Icons](https://akveo.github.io/eva-icons/) pack by default. * - * Basic alert example: - * @stacked-example(Showcase, alert/alert-showcase.component) + * Basic icon example: + * @stacked-example(Showcase, icon/icon-showcase.component) * - * Alert configuration: + * Icon configuration: * * ```html - * - * You have been successfully authenticated! - * + * * ``` * ### Installation * - * Import `NbButtonModule` to your feature module. + * By default Nebular comes without any pre-installed icon pack. + * Starting with Nebular 4.0.0 we ship separate package called `@nebular/eva-icons` + * which integrates SVG [Eva Icons](https://akveo.github.io/eva-icons/) pack to Nebular. To add it to your + * project run: + * ```sh + * npm i @nebular/eva-icons + * ``` + * This command will install Nebular Eva Icons pack. Then register `NbEvaIconsModule` into your app module or any child + * module you need to have the icons in: * ```ts + * import { NbEvaIconsModule } form '@nebular/eva-icons'; + * * @NgModule({ * imports: [ * // ... - * NbAlertModule, + * NbEvaIconsModule, + * ], + * }) + * export class PageModule { } + * ``` + * Last thing, import `NbIconModule` to your feature module where you need to show an icon: + * ```ts + * @NgModule({ + * imports: [ + * // ... + * NbIconModule, * ], * }) * export class PageModule { } * ``` * ### Usage * - * Alert could additionally have a `close` button when `closable` property is set: + * Icon can be colored using `status` input: * ```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) + * Colored icons: + * @stacked-example(Colored Icons, icon/icon-colors.component) * - * And `outline` property: - * @stacked-example(Outline Alert, alert/alert-outline.component) + * In case you need to specify an icon from a specific icon pack, this could be done using `pack` input property: + * ```html + * + * ``` + * Additional icon settings (if available by the icon pack) could be passed using `options` input: * - * @additional-example(Multiple Sizes, alert/alert-sizes.component) + * ```html + * + * ``` * * @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: + * icon-font-size: + * icon-width: + * icon-height: + * icon-primary-fg: + * icon-info-fg: + * icon-success-fg: + * icon-warning-fg: + * icon-danger-fg: */ @Component({ selector: 'nb-icon', @@ -140,22 +139,34 @@ export class NbIconComponent implements OnChanges, OnInit { return this.status === NbIconComponent.STATUS_DANGER; } + /** + * Icon name + * @param {string} status + */ @Input() icon: string; + /** + * Icon pack name + * @param {string} status + */ @Input() pack: string; + /** + * Additional icon settings + * @param {[name: string]: any} + */ @Input() options: { [name: string]: any }; /** * Icon status (adds specific styles): * primary, info, success, warning, danger - * @param {string} val + * @param {string} status */ @Input() status: string; constructor( private sanitizer: DomSanitizer, - private iconLibrary: NbIconsLibrary, + private iconLibrary: NbIconLibraries, private el: ElementRef, private renderer: Renderer2, ) {} diff --git a/src/framework/theme/components/icon/icon.module.ts b/src/framework/theme/components/icon/icon.module.ts index cc9fcb5138..97f1adf1da 100644 --- a/src/framework/theme/components/icon/icon.module.ts +++ b/src/framework/theme/components/icon/icon.module.ts @@ -8,7 +8,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NbIconComponent } from './icon.component'; -import { NbIconsLibrary } from './icons-library'; +import { NbIconLibraries } from './icon-libraries'; @NgModule({ imports: [ @@ -25,7 +25,7 @@ export class NbIconModule { private essentialsPackName = 'essentials'; - constructor(private iconsLibrary: NbIconsLibrary) { + constructor(private iconsLibrary: NbIconLibraries) { // in case of consequent calls we don't need to enable `essentials` pack again if (this.iconsLibrary.getPack(this.essentialsPackName)) { diff --git a/src/framework/theme/components/icon/icons-library.spec.ts b/src/framework/theme/components/icon/icons-libraries.spec.ts similarity index 96% rename from src/framework/theme/components/icon/icons-library.spec.ts rename to src/framework/theme/components/icon/icons-libraries.spec.ts index 131bc090c0..6a8f83778f 100644 --- a/src/framework/theme/components/icon/icons-library.spec.ts +++ b/src/framework/theme/components/icon/icons-libraries.spec.ts @@ -1,20 +1,20 @@ import { TestBed } from '@angular/core/testing'; -import { NbIconsLibrary } from './icons-library'; +import { NbIconLibraries } from './icon-libraries'; import { NbSvgIcon } from './icon'; describe('icons-library', () => { - let iconsLibrary: NbIconsLibrary; + let iconsLibrary: NbIconLibraries; beforeEach(() => { TestBed.resetTestingModule(); const bed = TestBed.configureTestingModule({ providers: [ - NbIconsLibrary, + NbIconLibraries, ], }); - iconsLibrary = bed.get(NbIconsLibrary); + iconsLibrary = bed.get(NbIconLibraries); }); it('should register raw svg icon', () => { diff --git a/src/framework/theme/index.ts b/src/framework/theme/index.ts index e9be0892c1..b3bc9364dc 100644 --- a/src/framework/theme/index.ts +++ b/src/framework/theme/index.ts @@ -103,4 +103,4 @@ 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'; +export * from './components/icon/icon-libraries'; diff --git a/src/playground/with-layout/icon/icon-showcase.component.html b/src/playground/with-layout/icon/icon-showcase.component.html index e6723fc74d..9033bceb67 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.html +++ b/src/playground/with-layout/icon/icon-showcase.component.html @@ -1,5 +1,6 @@ + diff --git a/src/playground/with-layout/icon/icon-showcase.component.ts b/src/playground/with-layout/icon/icon-showcase.component.ts index 6b157a7ba9..2c00405b6b 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.ts +++ b/src/playground/with-layout/icon/icon-showcase.component.ts @@ -20,6 +20,11 @@ export class IconShowcaseComponent { // - nebular eva icons // - how to use nebular font // packages smoke + // remove nebular icons + // replace feather icons + // add icons docs ICON + // update schematics + // breaking changes // do examples: // icon in button // icon prefix From 0e7837609a839357c6d7d34b8c96d00f8a7044a2 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Tue, 26 Mar 2019 19:26:25 +0300 Subject: [PATCH 25/33] feat(icon): add docs --- docs/articles/install-into-existing.md | 6 ++++++ docs/structure.ts | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/docs/articles/install-into-existing.md b/docs/articles/install-into-existing.md index 2d369e311b..df4165e94f 100644 --- a/docs/articles/install-into-existing.md +++ b/docs/articles/install-into-existing.md @@ -59,6 +59,12 @@ At this step, we assume you already have Angular modules installed. ```bash npm install --save @nebular/theme @angular/cdk @angular/animations ``` +Also, you may want to install Eva Icons pack, which is a recommended SVG icons library starting from Nebular 4.0. +```bash +npm install --save @nebular/eva-icons +``` +More details on [how to use Nebular Icons are here](docs/components/icon/overview#nbiconcomponent). + Additionally you can install Auth and Security `npm install --save @nebular/auth @nebular/security` diff --git a/docs/structure.ts b/docs/structure.ts index e5a9315d05..3482803ad9 100644 --- a/docs/structure.ts +++ b/docs/structure.ts @@ -420,6 +420,15 @@ export const structure = [ 'NbAlertComponent', ], }, + { + type: 'tabs', + name: 'Icon', + icon: 'icon.svg', + source: [ + 'NbIconComponent', + 'NbIconLibraries', + ], + }, { type: 'tabs', name: 'Spinner', From 88a2576d1f6dcaf656e3d1eeb5357c009d14833c Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Tue, 26 Mar 2019 19:27:24 +0300 Subject: [PATCH 26/33] refactor(docs): new eva-icons --- .../components/header/header.component.scss | 4 +- .../components/header/header.component.ts | 2 +- .../page-tabs/page-tabs.component.scss | 31 +- .../page-tabs/page-tabs.component.ts | 10 +- .../components/search/search.component.scss | 2 +- .../components/search/search.component.ts | 2 +- docs/app/@theme/styles/_feather.scss | 569 ------------------ docs/app/@theme/styles/styles.scss | 1 - docs/app/@theme/theme.module.ts | 6 + .../live-example-block.component.html | 8 +- .../live-example-block.component.scss | 6 +- .../pager-block/pager-block.component.scss | 2 +- .../pager-block/pager-block.component.ts | 4 +- .../tabbed-example-block.component.html | 2 +- .../tabbed-example-block.component.scss | 5 +- .../theme-block/theme-block.component.html | 2 +- .../theme-block/theme-block.component.scss | 2 + .../documentation.component.scss | 4 + docs/app/example/example-404.component.scss | 2 +- docs/app/example/example-404.component.ts | 4 +- docs/app/example/example.module.ts | 2 - .../icon/icon-showcase.component.ts | 23 +- 22 files changed, 55 insertions(+), 638 deletions(-) delete mode 100644 docs/app/@theme/styles/_feather.scss diff --git a/docs/app/@theme/components/header/header.component.scss b/docs/app/@theme/components/header/header.component.scss index 77eb3773bc..f2280dea68 100644 --- a/docs/app/@theme/components/header/header.component.scss +++ b/docs/app/@theme/components/header/header.component.scss @@ -22,8 +22,10 @@ flex: 1 0 auto; padding: 0 0.5rem; - .nb-menu { + nb-icon { vertical-align: middle; + font-size: 1.75rem; + color: $version-fg; } } diff --git a/docs/app/@theme/components/header/header.component.ts b/docs/app/@theme/components/header/header.component.ts index 7071250423..e630a56223 100644 --- a/docs/app/@theme/components/header/header.component.ts +++ b/docs/app/@theme/components/header/header.component.ts @@ -8,7 +8,7 @@ import { NgdVersionService } from '../../services'; template: ` - + Nebular diff --git a/docs/app/@theme/components/page-tabs/page-tabs.component.scss b/docs/app/@theme/components/page-tabs/page-tabs.component.scss index 071b33f37d..387f00de15 100644 --- a/docs/app/@theme/components/page-tabs/page-tabs.component.scss +++ b/docs/app/@theme/components/page-tabs/page-tabs.component.scss @@ -28,9 +28,15 @@ font-weight: 500; } - .icon { - font-size: 1.5rem; - padding-bottom: 1rem; + .text-container { + display: flex; + flex-direction: column; + align-items: center; + } + + ::ng-deep nb-icon { + font-size: 1.875rem; + margin-bottom: 1rem; } &.selected { @@ -46,12 +52,6 @@ } } } - - .icon, - .title { - display: block; - text-align: center; - } } :host(.horizontal) { @@ -62,19 +62,15 @@ padding: 0 1rem; .title, - .icon { - display: inline; - padding-bottom: 0; - vertical-align: middle; - } - - .icon { + ::ng-deep nb-icon { + margin-bottom: 1rem; margin-right: 0.5rem; } } .text-container { - padding-bottom: 1.3rem; + flex-direction: row; + padding-bottom: 0; } .line { @@ -87,6 +83,7 @@ a { flex: 1 1 0; + margin-bottom: 0; &.selected::after { content: ''; diff --git a/docs/app/@theme/components/page-tabs/page-tabs.component.ts b/docs/app/@theme/components/page-tabs/page-tabs.component.ts index 427f9b0c9c..596678b27e 100644 --- a/docs/app/@theme/components/page-tabs/page-tabs.component.ts +++ b/docs/app/@theme/components/page-tabs/page-tabs.component.ts @@ -15,7 +15,7 @@ import { Observable, of as observableOf, combineLatest } from 'rxjs'; template: ` - + {{ item.title }} @@ -57,23 +57,23 @@ export class NgdPageTabsComponent implements OnDestroy { { tab: 'overview', title: 'Overview', - icon: 'feather-eye', + icon: 'eye-outline', selected: true, }, { tab: 'api', title: 'API', - icon: 'feather-settings', + icon: 'settings-outline', }, { tab: 'theme', title: 'Theme', - icon: 'feather-droplet', + icon: 'droplet-outline', }, { tab: 'examples', title: 'Examples', - icon: 'feather-image', + icon: 'image-outline', }, ]; private alive = true; diff --git a/docs/app/@theme/components/search/search.component.scss b/docs/app/@theme/components/search/search.component.scss index 4da27fbd9f..baa997940c 100644 --- a/docs/app/@theme/components/search/search.component.scss +++ b/docs/app/@theme/components/search/search.component.scss @@ -18,7 +18,7 @@ } } - .icon { + nb-icon { color: $fg; position: absolute; top: 50%; diff --git a/docs/app/@theme/components/search/search.component.ts b/docs/app/@theme/components/search/search.component.ts index 91f69e496d..0d69abe7cd 100644 --- a/docs/app/@theme/components/search/search.component.ts +++ b/docs/app/@theme/components/search/search.component.ts @@ -5,7 +5,7 @@ import { NB_WINDOW } from '@nebular/theme'; selector: 'ngd-search', styleUrls: ['./search.component.scss'], template: ` - + `, changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/docs/app/@theme/styles/_feather.scss b/docs/app/@theme/styles/_feather.scss deleted file mode 100644 index bd40e0f7d7..0000000000 --- a/docs/app/@theme/styles/_feather.scss +++ /dev/null @@ -1,569 +0,0 @@ -$feather-font-path: '/assets/fonts/feather' !default; -@font-face { - font-family: 'feather'; - src: url('#{$feather-font-path}/feather.eot?skntni'); - src: url('#{$feather-font-path}/feather.eot?skntni#iefix') format('embedded-opentype'), - url('#{$feather-font-path}/feather.ttf?skntni') format('truetype'), - url('#{$feather-font-path}/feather.woff?skntni') format('woff'), - url('#{$feather-font-path}/feather.svg?skntni#feather') format('svg'); - font-weight: normal; - font-style: normal; -} - -[class^='feather-'], [class*=' feather-'] { - font-family: 'feather' !important; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.feather-alert-octagon::before { content: '\e81b'; } - -.feather-alert-circle::before { content: '\e81c'; } - -.feather-activity::before { content: '\e81d'; } - -.feather-alert-triangle::before { content: '\e81e'; } - -.feather-align-center::before { content: '\e81f'; } - -.feather-airplay::before { content: '\e820'; } - -.feather-align-justify::before { content: '\e821'; } - -.feather-align-left::before { content: '\e822'; } - -.feather-align-right::before { content: '\e823'; } - -.feather-arrow-down-left::before { content: '\e824'; } - -.feather-arrow-down-right::before { content: '\e825'; } - -.feather-anchor::before { content: '\e826'; } - -.feather-aperture::before { content: '\e827'; } - -.feather-arrow-left::before { content: '\e828'; } - -.feather-arrow-right::before { content: '\e829'; } - -.feather-arrow-down::before { content: '\e82a'; } - -.feather-arrow-up-left::before { content: '\e82b'; } - -.feather-arrow-up-right::before { content: '\e82c'; } - -.feather-arrow-up::before { content: '\e82d'; } - -.feather-award::before { content: '\e82e'; } - -.feather-bar-chart::before { content: '\e82f'; } - -.feather-at-sign::before { content: '\e830'; } - -.feather-bar-chart-2::before { content: '\e831'; } - -.feather-battery-charging::before { content: '\e832'; } - -.feather-bell-off::before { content: '\e833'; } - -.feather-battery::before { content: '\e834'; } - -.feather-bluetooth::before { content: '\e835'; } - -.feather-bell::before { content: '\e836'; } - -.feather-book::before { content: '\e837'; } - -.feather-briefcase::before { content: '\e838'; } - -.feather-camera-off::before { content: '\e839'; } - -.feather-calendar::before { content: '\e83a'; } - -.feather-bookmark::before { content: '\e83b'; } - -.feather-box::before { content: '\e83c'; } - -.feather-camera::before { content: '\e83d'; } - -.feather-check-circle::before { content: '\e83e'; } - -.feather-check::before { content: '\e83f'; } - -.feather-check-square::before { content: '\e840'; } - -.feather-cast::before { content: '\e841'; } - -.feather-chevron-down::before { content: '\e842'; } - -.feather-chevron-left::before { content: '\e843'; } - -.feather-chevron-right::before { content: '\e844'; } - -.feather-chevron-up::before { content: '\e845'; } - -.feather-chevrons-down::before { content: '\e846'; } - -.feather-chevrons-right::before { content: '\e847'; } - -.feather-chevrons-up::before { content: '\e848'; } - -.feather-chevrons-left::before { content: '\e849'; } - -.feather-circle::before { content: '\e84a'; } - -.feather-clipboard::before { content: '\e84b'; } - -.feather-chrome::before { content: '\e84c'; } - -.feather-clock::before { content: '\e84d'; } - -.feather-cloud-lightning::before { content: '\e84e'; } - -.feather-cloud-drizzle::before { content: '\e84f'; } - -.feather-cloud-rain::before { content: '\e850'; } - -.feather-cloud-off::before { content: '\e851'; } - -.feather-codepen::before { content: '\e852'; } - -.feather-cloud-snow::before { content: '\e853'; } - -.feather-compass::before { content: '\e854'; } - -.feather-copy::before { content: '\e855'; } - -.feather-corner-down-right::before { content: '\e856'; } - -.feather-corner-down-left::before { content: '\e857'; } - -.feather-corner-left-down::before { content: '\e858'; } - -.feather-corner-left-up::before { content: '\e859'; } - -.feather-corner-up-left::before { content: '\e85a'; } - -.feather-corner-up-right::before { content: '\e85b'; } - -.feather-corner-right-down::before { content: '\e85c'; } - -.feather-corner-right-up::before { content: '\e85d'; } - -.feather-cpu::before { content: '\e85e'; } - -.feather-credit-card::before { content: '\e85f'; } - -.feather-crosshair::before { content: '\e860'; } - -.feather-disc::before { content: '\e861'; } - -.feather-delete::before { content: '\e862'; } - -.feather-download-cloud::before { content: '\e863'; } - -.feather-download::before { content: '\e864'; } - -.feather-droplet::before { content: '\e865'; } - -.feather-edit-2::before { content: '\e866'; } - -.feather-edit::before { content: '\e867'; } - -.feather-edit-1::before { content: '\e868'; } - -.feather-external-link::before { content: '\e869'; } - -.feather-eye::before { content: '\e86a'; } - -.feather-feather::before { content: '\e86b'; } - -.feather-facebook::before { content: '\e86c'; } - -.feather-file-minus::before { content: '\e86d'; } - -.feather-eye-off::before { content: '\e86e'; } - -.feather-fast-forward::before { content: '\e86f'; } - -.feather-file-text::before { content: '\e870'; } - -.feather-film::before { content: '\e871'; } - -.feather-file::before { content: '\e872'; } - -.feather-file-plus::before { content: '\e873'; } - -.feather-folder::before { content: '\e874'; } - -.feather-filter::before { content: '\e875'; } - -.feather-flag::before { content: '\e876'; } - -.feather-globe::before { content: '\e877'; } - -.feather-grid::before { content: '\e878'; } - -.feather-heart::before { content: '\e879'; } - -.feather-home::before { content: '\e87a'; } - -.feather-github::before { content: '\e87b'; } - -.feather-image::before { content: '\e87c'; } - -.feather-inbox::before { content: '\e87d'; } - -.feather-layers::before { content: '\e87e'; } - -.feather-info::before { content: '\e87f'; } - -.feather-instagram::before { content: '\e880'; } - -.feather-layout::before { content: '\e881'; } - -.feather-link-2::before { content: '\e882'; } - -.feather-life-buoy::before { content: '\e883'; } - -.feather-link::before { content: '\e884'; } - -.feather-log-in::before { content: '\e885'; } - -.feather-list::before { content: '\e886'; } - -.feather-lock::before { content: '\e887'; } - -.feather-log-out::before { content: '\e888'; } - -.feather-loader::before { content: '\e889'; } - -.feather-mail::before { content: '\e88a'; } - -.feather-maximize-2::before { content: '\e88b'; } - -.feather-map::before { content: '\e88c'; } - -.feather-map-pin::before { content: '\e88e'; } - -.feather-menu::before { content: '\e88f'; } - -.feather-message-circle::before { content: '\e890'; } - -.feather-message-square::before { content: '\e891'; } - -.feather-minimize-2::before { content: '\e892'; } - -.feather-mic-off::before { content: '\e893'; } - -.feather-minus-circle::before { content: '\e894'; } - -.feather-mic::before { content: '\e895'; } - -.feather-minus-square::before { content: '\e896'; } - -.feather-minus::before { content: '\e897'; } - -.feather-moon::before { content: '\e898'; } - -.feather-monitor::before { content: '\e899'; } - -.feather-more-vertical::before { content: '\e89a'; } - -.feather-more-horizontal::before { content: '\e89b'; } - -.feather-move::before { content: '\e89c'; } - -.feather-music::before { content: '\e89d'; } - -.feather-navigation-2::before { content: '\e89e'; } - -.feather-navigation::before { content: '\e89f'; } - -.feather-octagon::before { content: '\e8a0'; } - -.feather-package::before { content: '\e8a1'; } - -.feather-pause-circle::before { content: '\e8a2'; } - -.feather-pause::before { content: '\e8a3'; } - -.feather-percent::before { content: '\e8a4'; } - -.feather-phone-call::before { content: '\e8a5'; } - -.feather-phone-forwarded::before { content: '\e8a6'; } - -.feather-phone-missed::before { content: '\e8a7'; } - -.feather-phone-off::before { content: '\e8a8'; } - -.feather-phone-incoming::before { content: '\e8a9'; } - -.feather-phone::before { content: '\e8aa'; } - -.feather-phone-outgoing::before { content: '\e8ab'; } - -.feather-pie-chart::before { content: '\e8ac'; } - -.feather-play-circle::before { content: '\e8ad'; } - -.feather-play::before { content: '\e8ae'; } - -.feather-plus-square::before { content: '\e8af'; } - -.feather-plus-circle::before { content: '\e8b0'; } - -.feather-plus::before { content: '\e8b1'; } - -.feather-pocket::before { content: '\e8b2'; } - -.feather-printer::before { content: '\e8b3'; } - -.feather-power::before { content: '\e8b4'; } - -.feather-radio::before { content: '\e8b5'; } - -.feather-repeat::before { content: '\e8b6'; } - -.feather-refresh-ccw::before { content: '\e8b7'; } - -.feather-rewind::before { content: '\e8b8'; } - -.feather-rotate-ccw::before { content: '\e8b9'; } - -.feather-refresh-cw::before { content: '\e8ba'; } - -.feather-rotate-cw::before { content: '\e8bb'; } - -.feather-save::before { content: '\e8bc'; } - -.feather-search::before { content: '\e8bd'; } - -.feather-server::before { content: '\e8be'; } - -.feather-scissors::before { content: '\e8bf'; } - -.feather-share-2::before { content: '\e8c0'; } - -.feather-share::before { content: '\e8c1'; } - -.feather-shield::before { content: '\e8c2'; } - -.feather-settings::before { content: '\e8c3'; } - -.feather-skip-back::before { content: '\e8c4'; } - -.feather-shuffle::before { content: '\e8c5'; } - -.feather-sidebar::before { content: '\e8c6'; } - -.feather-skip-forward::before { content: '\e8c7'; } - -.feather-slack::before { content: '\e8c8'; } - -.feather-slash::before { content: '\e8c9'; } - -.feather-smartphone::before { content: '\e8ca'; } - -.feather-square::before { content: '\e8cb'; } - -.feather-speaker::before { content: '\e8cc'; } - -.feather-star::before { content: '\e8cd'; } - -.feather-stop-circle::before { content: '\e8ce'; } - -.feather-sun::before { content: '\e8cf'; } - -.feather-sunrise::before { content: '\e8d0'; } - -.feather-tablet::before { content: '\e8d1'; } - -.feather-tag::before { content: '\e8d2'; } - -.feather-sunset::before { content: '\e8d3'; } - -.feather-target::before { content: '\e8d4'; } - -.feather-thermometer::before { content: '\e8d5'; } - -.feather-thumbs-up::before { content: '\e8d6'; } - -.feather-thumbs-down::before { content: '\e8d7'; } - -.feather-toggle-left::before { content: '\e8d8'; } - -.feather-toggle-right::before { content: '\e8d9'; } - -.feather-trash-2::before { content: '\e8da'; } - -.feather-trash::before { content: '\e8db'; } - -.feather-trending-up::before { content: '\e8dc'; } - -.feather-trending-down::before { content: '\e8dd'; } - -.feather-triangle::before { content: '\e8de'; } - -.feather-type::before { content: '\e8df'; } - -.feather-twitter::before { content: '\e8e0'; } - -.feather-upload::before { content: '\e8e1'; } - -.feather-umbrella::before { content: '\e8e2'; } - -.feather-upload-cloud::before { content: '\e8e3'; } - -.feather-unlock::before { content: '\e8e4'; } - -.feather-user-check::before { content: '\e8e5'; } - -.feather-user-minus::before { content: '\e8e6'; } - -.feather-user-plus::before { content: '\e8e7'; } - -.feather-user-x::before { content: '\e8e8'; } - -.feather-user::before { content: '\e8e9'; } - -.feather-users::before { content: '\e8ea'; } - -.feather-video-off::before { content: '\e8eb'; } - -.feather-video::before { content: '\e8ec'; } - -.feather-voicemail::before { content: '\e8ed'; } - -.feather-volume-x::before { content: '\e8ee'; } - -.feather-volume-2::before { content: '\e8ef'; } - -.feather-volume-1::before { content: '\e8f0'; } - -.feather-volume::before { content: '\e8f1'; } - -.feather-watch::before { content: '\e8f2'; } - -.feather-wifi::before { content: '\e8f3'; } - -.feather-x-square::before { content: '\e8f4'; } - -.feather-wind::before { content: '\e8f5'; } - -.feather-x::before { content: '\e8f6'; } - -.feather-x-circle::before { content: '\e8f7'; } - -.feather-zap::before { content: '\e8f8'; } - -.feather-zoom-in::before { content: '\e8f9'; } - -.feather-zoom-out::before { content: '\e8fa'; } - -.feather-command::before { content: '\e8fb'; } - -.feather-cloud::before { content: '\e8fc'; } - -.feather-hash::before { content: '\e8fd'; } - -.feather-headphones::before { content: '\e8fe'; } - -.feather-underline::before { content: '\e8ff'; } - -.feather-italic::before { content: '\e900'; } - -.feather-bold::before { content: '\e901'; } - -.feather-crop::before { content: '\e902'; } - -.feather-help-circle::before { content: '\e903'; } - -.feather-paperclip::before { content: '\e904'; } - -.feather-shopping-cart::before { content: '\e905'; } - -.feather-tv::before { content: '\e906'; } - -.feather-wifi-off::before { content: '\e907'; } - -.feather-minimize::before { content: '\e88d'; } - -.feather-maximize::before { content: '\e908'; } - -.feather-gitlab::before { content: '\e909'; } - -.feather-sliders::before { content: '\e90a'; } - -.feather-star-on::before { content: '\e90b'; } - -.feather-heart-on::before { content: '\e90c'; } - -.feather-archive::before { content: '\e90d'; } - -.feather-arrow-down-circle::before { content: '\e90e'; } - -.feather-arrow-up-circle::before { content: '\e90f'; } - -.feather-arrow-left-circle::before { content: '\e910'; } - -.feather-arrow-right-circle::before { content: '\e911'; } - -.feather-bar-chart-line-::before { content: '\e912'; } - -.feather-bar-chart-line::before { content: '\e913'; } - -.feather-book-open::before { content: '\e914'; } - -.feather-code::before { content: '\e915'; } - -.feather-database::before { content: '\e916'; } - -.feather-dollar-sign::before { content: '\e917'; } - -.feather-folder-plus::before { content: '\e918'; } - -.feather-gift::before { content: '\e919'; } - -.feather-folder-minus::before { content: '\e91a'; } - -.feather-git-commit::before { content: '\e91b'; } - -.feather-git-branch::before { content: '\e91c'; } - -.feather-git-pull-request::before { content: '\e91d'; } - -.feather-git-merge::before { content: '\e91e'; } - -.feather-linkedin::before { content: '\e91f'; } - -.feather-hard-drive::before { content: '\e920'; } - -.feather-more-vertical-::before { content: '\e921'; } - -.feather-more-horizontal-::before { content: '\e922'; } - -.feather-rss::before { content: '\e923'; } - -.feather-send::before { content: '\e924'; } - -.feather-shield-off::before { content: '\e925'; } - -.feather-shopping-bag::before { content: '\e926'; } - -.feather-terminal::before { content: '\e927'; } - -.feather-truck::before { content: '\e928'; } - -.feather-zap-off::before { content: '\e929'; } - -.feather-youtube::before { content: '\e92a'; } diff --git a/docs/app/@theme/styles/styles.scss b/docs/app/@theme/styles/styles.scss index 92fc1d64a6..5537857ffa 100644 --- a/docs/app/@theme/styles/styles.scss +++ b/docs/app/@theme/styles/styles.scss @@ -1,7 +1,6 @@ @import 'themes'; @import 'common'; @import 'small-social'; -@import 'feather'; @import '../../../../src/framework/theme/styles/global/normalize'; @import '../../../../src/framework/theme/styles/global/components'; diff --git a/docs/app/@theme/theme.module.ts b/docs/app/@theme/theme.module.ts index 426ea75f78..971af1da0b 100644 --- a/docs/app/@theme/theme.module.ts +++ b/docs/app/@theme/theme.module.ts @@ -16,8 +16,11 @@ import { NbSidebarModule, NbCardModule, NbCheckboxModule, + NbIconModule, } from '@nebular/theme'; +import { NbEvaIconsModule } from '@nebular/eva-icons'; + import { NgdHeaderComponent, NgdHeroComponent, @@ -57,6 +60,8 @@ import { NbCardModule, NbMenuModule, NbTabsetModule, + NbIconModule, + NbEvaIconsModule, RouterModule, ], declarations: [ @@ -77,6 +82,7 @@ import { RouterModule, ReactiveFormsModule, FormsModule, + NbIconModule, NbLayoutModule, NbSidebarModule, NbCardModule, diff --git a/docs/app/blocks/components/live-example-block/live-example-block.component.html b/docs/app/blocks/components/live-example-block/live-example-block.component.html index 3262fa2c4a..419c0e6445 100644 --- a/docs/app/blocks/components/live-example-block/live-example-block.component.html +++ b/docs/app/blocks/components/live-example-block/live-example-block.component.html @@ -6,20 +6,20 @@ {{theme.label}} - + - + - + - + diff --git a/docs/app/blocks/components/live-example-block/live-example-block.component.scss b/docs/app/blocks/components/live-example-block/live-example-block.component.scss index 2182194854..e5ec9a957b 100644 --- a/docs/app/blocks/components/live-example-block/live-example-block.component.scss +++ b/docs/app/blocks/components/live-example-block/live-example-block.component.scss @@ -40,7 +40,7 @@ display: flex; width: 100%; - .icon { + nb-icon { font-size: 0.95rem; } } @@ -73,7 +73,7 @@ color: transparent; } - .icon { + nb-icon { color: $action-fg; position: absolute; top: 50%; @@ -156,7 +156,7 @@ padding: 0 2.5rem; } - .icon { + nb-icon { left: 1.25rem; transform: translate(0, -50%); } diff --git a/docs/app/blocks/components/pager-block/pager-block.component.scss b/docs/app/blocks/components/pager-block/pager-block.component.scss index 90e6c269fc..eea8c64725 100644 --- a/docs/app/blocks/components/pager-block/pager-block.component.scss +++ b/docs/app/blocks/components/pager-block/pager-block.component.scss @@ -32,7 +32,7 @@ font-weight: 500; font-size: 1.2rem; - i { + nb-icon { color: $arrow-fg; margin-top: 0.3rem; } diff --git a/docs/app/blocks/components/pager-block/pager-block.component.ts b/docs/app/blocks/components/pager-block/pager-block.component.ts index 2865311470..48c90e422a 100644 --- a/docs/app/blocks/components/pager-block/pager-block.component.ts +++ b/docs/app/blocks/components/pager-block/pager-block.component.ts @@ -11,7 +11,7 @@ import { NgdPaginationService } from '../../../@theme/services'; - + {{ paginationItem.prev.title }} Previous page @@ -23,7 +23,7 @@ import { NgdPaginationService } from '../../../@theme/services'; [attr.title]="paginationItem.next.title"> {{ paginationItem.next.title }} - + Next page diff --git a/docs/app/blocks/components/tabbed-example-block/tabbed-example-block.component.html b/docs/app/blocks/components/tabbed-example-block/tabbed-example-block.component.html index c449372404..432cfa3080 100644 --- a/docs/app/blocks/components/tabbed-example-block/tabbed-example-block.component.html +++ b/docs/app/blocks/components/tabbed-example-block/tabbed-example-block.component.html @@ -2,7 +2,7 @@ *ngIf="hasViewSwitch" class="btn action-item action-button" (click)="switchToLiveView()"> - + Live view diff --git a/docs/app/blocks/components/tabbed-example-block/tabbed-example-block.component.scss b/docs/app/blocks/components/tabbed-example-block/tabbed-example-block.component.scss index 253f48115e..b9a62d2c0d 100644 --- a/docs/app/blocks/components/tabbed-example-block/tabbed-example-block.component.scss +++ b/docs/app/blocks/components/tabbed-example-block/tabbed-example-block.component.scss @@ -22,8 +22,9 @@ font-weight: normal; font-size: 0.9rem; - .icon { - font-size: 0.95rem; + nb-icon { + font-size: 1rem; + vertical-align: middle; } &:focus, &:active, &:hover { diff --git a/docs/app/blocks/components/theme-block/theme-block.component.html b/docs/app/blocks/components/theme-block/theme-block.component.html index 56b9a9f7db..e35d65ee5f 100644 --- a/docs/app/blocks/components/theme-block/theme-block.component.html +++ b/docs/app/blocks/components/theme-block/theme-block.component.html @@ -31,7 +31,7 @@ {{ vm.themeTitle }} Theme 0" *ngFor="let parent of prop.parents; let index = index"> - 0" class="inheritance-icon feather-arrow-left"> + 0" class="inheritance-icon" icon="arrow-back-outline"> {{ parent.prop }} ({{ parent.theme }}) diff --git a/docs/app/blocks/components/theme-block/theme-block.component.scss b/docs/app/blocks/components/theme-block/theme-block.component.scss index 247a848abb..b952940d10 100644 --- a/docs/app/blocks/components/theme-block/theme-block.component.scss +++ b/docs/app/blocks/components/theme-block/theme-block.component.scss @@ -9,7 +9,9 @@ $selected-row-bg: nb-theme(color-gray-light); .inheritance-icon { + font-size: 1rem; margin: 0 0.25rem; + vertical-align: middle; } .inheritance-property { diff --git a/docs/app/documentation/documentation.component.scss b/docs/app/documentation/documentation.component.scss index d2b253381d..d620435cc3 100644 --- a/docs/app/documentation/documentation.component.scss +++ b/docs/app/documentation/documentation.component.scss @@ -76,6 +76,10 @@ } } + nb-icon { + display: none; + } + .menu-items .menu-item .menu-item a { &:hover, &.active, &:focus { text-shadow: 0.5px 0 0 currentColor; diff --git a/docs/app/example/example-404.component.scss b/docs/app/example/example-404.component.scss index 6457cca5a5..50b8c3282e 100644 --- a/docs/app/example/example-404.component.scss +++ b/docs/app/example/example-404.component.scss @@ -1,4 +1,4 @@ -::ng-deep nb-layout-column { +:host { align-items: center; display: flex; color: gray; diff --git a/docs/app/example/example-404.component.ts b/docs/app/example/example-404.component.ts index 727fe1ff18..28f3aabe9b 100644 --- a/docs/app/example/example-404.component.ts +++ b/docs/app/example/example-404.component.ts @@ -4,9 +4,7 @@ import { NbThemeService } from '@nebular/theme'; @Component({ selector: 'ngd-example-404', template: ` - - Example not found. - + Example not found. `, styleUrls: ['./example-404.component.scss'], }) diff --git a/docs/app/example/example.module.ts b/docs/app/example/example.module.ts index a18eaf05c1..c433862c66 100644 --- a/docs/app/example/example.module.ts +++ b/docs/app/example/example.module.ts @@ -8,14 +8,12 @@ import { NgModule } from '@angular/core'; import { NgdExampleRoutingModule } from './example-routing.module'; import { NgdExampleComponent } from './example.component'; -import { NgdThemeModule } from '../@theme/theme.module'; import { NgdExample404Component } from './example-404.component'; @NgModule({ imports: [ NgdExampleRoutingModule, - NgdThemeModule, ], declarations: [ NgdExampleComponent, diff --git a/src/playground/with-layout/icon/icon-showcase.component.ts b/src/playground/with-layout/icon/icon-showcase.component.ts index 2c00405b6b..a2e3221506 100644 --- a/src/playground/with-layout/icon/icon-showcase.component.ts +++ b/src/playground/with-layout/icon/icon-showcase.component.ts @@ -13,26 +13,5 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; }) export class IconShowcaseComponent { - constructor() { - - // migration strategy (for nebular icons, and when eva becomes default) - // - essential icons - // - nebular eva icons - // - how to use nebular font - // packages smoke - // remove nebular icons - // replace feather icons - // add icons docs ICON - // update schematics - // breaking changes - // 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 - // TODO: STATUS ICONS - } + constructor() { } } From 80e632e3d2230bda7232b3638d4a7894cf541e31 Mon Sep 17 00:00:00 2001 From: Dmitry Nehaychik <4dmitr@gmail.com> Date: Wed, 27 Mar 2019 18:23:24 +0300 Subject: [PATCH 27/33] refactor(icons): multiple fixes --- docs/app/@theme/styles/_feather.scss | 569 ++++++++++++ docs/assets/fonts/feather/feather.eot | Bin 62084 -> 0 bytes docs/assets/fonts/feather/feather.svg | 849 ------------------ docs/assets/fonts/feather/feather.ttf | Bin 61920 -> 0 bytes docs/assets/fonts/feather/feather.woff | Bin 29500 -> 0 bytes docs/assets/images/components/icon.svg | 196 ++++ src/app/app.module.ts | 2 + src/framework/eva-icons/eva-icons.module.ts | 8 +- .../accordion-item-header.component.ts | 3 +- .../components/button/button.component.scss | 4 +- .../components/button/button.component.ts | 4 +- .../components/chat/chat-form.component.ts | 4 +- .../chat/chat-message-file.component.ts | 2 +- .../theme/components/icon/icon-libraries.ts | 53 +- .../theme/components/icon/icon-pack.ts | 5 +- .../theme/components/icon/icon.component.ts | 19 +- .../theme/components/icon/icon.module.ts | 8 +- .../theme/components/icon/icon.spec.ts | 8 +- src/framework/theme/components/icon/icon.ts | 16 +- .../components/icon/icons-libraries.spec.ts | 18 +- .../components/menu/menu-item.component.html | 3 +- .../components/search/search.component.ts | 4 +- .../components/stepper/stepper.component.html | 3 +- .../components/toastr/toast.component.html | 2 +- .../tree-grid-row-toggle.component.ts | 2 +- .../tree-grid/tree-grid-sort.component.ts | 4 +- .../components/window/window.component.ts | 8 +- src/playground/playground.module.ts | 3 +- 28 files changed, 862 insertions(+), 935 deletions(-) create mode 100644 docs/app/@theme/styles/_feather.scss delete mode 100755 docs/assets/fonts/feather/feather.eot delete mode 100755 docs/assets/fonts/feather/feather.svg delete mode 100755 docs/assets/fonts/feather/feather.ttf delete mode 100755 docs/assets/fonts/feather/feather.woff create mode 100644 docs/assets/images/components/icon.svg diff --git a/docs/app/@theme/styles/_feather.scss b/docs/app/@theme/styles/_feather.scss new file mode 100644 index 0000000000..bd40e0f7d7 --- /dev/null +++ b/docs/app/@theme/styles/_feather.scss @@ -0,0 +1,569 @@ +$feather-font-path: '/assets/fonts/feather' !default; +@font-face { + font-family: 'feather'; + src: url('#{$feather-font-path}/feather.eot?skntni'); + src: url('#{$feather-font-path}/feather.eot?skntni#iefix') format('embedded-opentype'), + url('#{$feather-font-path}/feather.ttf?skntni') format('truetype'), + url('#{$feather-font-path}/feather.woff?skntni') format('woff'), + url('#{$feather-font-path}/feather.svg?skntni#feather') format('svg'); + font-weight: normal; + font-style: normal; +} + +[class^='feather-'], [class*=' feather-'] { + font-family: 'feather' !important; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.feather-alert-octagon::before { content: '\e81b'; } + +.feather-alert-circle::before { content: '\e81c'; } + +.feather-activity::before { content: '\e81d'; } + +.feather-alert-triangle::before { content: '\e81e'; } + +.feather-align-center::before { content: '\e81f'; } + +.feather-airplay::before { content: '\e820'; } + +.feather-align-justify::before { content: '\e821'; } + +.feather-align-left::before { content: '\e822'; } + +.feather-align-right::before { content: '\e823'; } + +.feather-arrow-down-left::before { content: '\e824'; } + +.feather-arrow-down-right::before { content: '\e825'; } + +.feather-anchor::before { content: '\e826'; } + +.feather-aperture::before { content: '\e827'; } + +.feather-arrow-left::before { content: '\e828'; } + +.feather-arrow-right::before { content: '\e829'; } + +.feather-arrow-down::before { content: '\e82a'; } + +.feather-arrow-up-left::before { content: '\e82b'; } + +.feather-arrow-up-right::before { content: '\e82c'; } + +.feather-arrow-up::before { content: '\e82d'; } + +.feather-award::before { content: '\e82e'; } + +.feather-bar-chart::before { content: '\e82f'; } + +.feather-at-sign::before { content: '\e830'; } + +.feather-bar-chart-2::before { content: '\e831'; } + +.feather-battery-charging::before { content: '\e832'; } + +.feather-bell-off::before { content: '\e833'; } + +.feather-battery::before { content: '\e834'; } + +.feather-bluetooth::before { content: '\e835'; } + +.feather-bell::before { content: '\e836'; } + +.feather-book::before { content: '\e837'; } + +.feather-briefcase::before { content: '\e838'; } + +.feather-camera-off::before { content: '\e839'; } + +.feather-calendar::before { content: '\e83a'; } + +.feather-bookmark::before { content: '\e83b'; } + +.feather-box::before { content: '\e83c'; } + +.feather-camera::before { content: '\e83d'; } + +.feather-check-circle::before { content: '\e83e'; } + +.feather-check::before { content: '\e83f'; } + +.feather-check-square::before { content: '\e840'; } + +.feather-cast::before { content: '\e841'; } + +.feather-chevron-down::before { content: '\e842'; } + +.feather-chevron-left::before { content: '\e843'; } + +.feather-chevron-right::before { content: '\e844'; } + +.feather-chevron-up::before { content: '\e845'; } + +.feather-chevrons-down::before { content: '\e846'; } + +.feather-chevrons-right::before { content: '\e847'; } + +.feather-chevrons-up::before { content: '\e848'; } + +.feather-chevrons-left::before { content: '\e849'; } + +.feather-circle::before { content: '\e84a'; } + +.feather-clipboard::before { content: '\e84b'; } + +.feather-chrome::before { content: '\e84c'; } + +.feather-clock::before { content: '\e84d'; } + +.feather-cloud-lightning::before { content: '\e84e'; } + +.feather-cloud-drizzle::before { content: '\e84f'; } + +.feather-cloud-rain::before { content: '\e850'; } + +.feather-cloud-off::before { content: '\e851'; } + +.feather-codepen::before { content: '\e852'; } + +.feather-cloud-snow::before { content: '\e853'; } + +.feather-compass::before { content: '\e854'; } + +.feather-copy::before { content: '\e855'; } + +.feather-corner-down-right::before { content: '\e856'; } + +.feather-corner-down-left::before { content: '\e857'; } + +.feather-corner-left-down::before { content: '\e858'; } + +.feather-corner-left-up::before { content: '\e859'; } + +.feather-corner-up-left::before { content: '\e85a'; } + +.feather-corner-up-right::before { content: '\e85b'; } + +.feather-corner-right-down::before { content: '\e85c'; } + +.feather-corner-right-up::before { content: '\e85d'; } + +.feather-cpu::before { content: '\e85e'; } + +.feather-credit-card::before { content: '\e85f'; } + +.feather-crosshair::before { content: '\e860'; } + +.feather-disc::before { content: '\e861'; } + +.feather-delete::before { content: '\e862'; } + +.feather-download-cloud::before { content: '\e863'; } + +.feather-download::before { content: '\e864'; } + +.feather-droplet::before { content: '\e865'; } + +.feather-edit-2::before { content: '\e866'; } + +.feather-edit::before { content: '\e867'; } + +.feather-edit-1::before { content: '\e868'; } + +.feather-external-link::before { content: '\e869'; } + +.feather-eye::before { content: '\e86a'; } + +.feather-feather::before { content: '\e86b'; } + +.feather-facebook::before { content: '\e86c'; } + +.feather-file-minus::before { content: '\e86d'; } + +.feather-eye-off::before { content: '\e86e'; } + +.feather-fast-forward::before { content: '\e86f'; } + +.feather-file-text::before { content: '\e870'; } + +.feather-film::before { content: '\e871'; } + +.feather-file::before { content: '\e872'; } + +.feather-file-plus::before { content: '\e873'; } + +.feather-folder::before { content: '\e874'; } + +.feather-filter::before { content: '\e875'; } + +.feather-flag::before { content: '\e876'; } + +.feather-globe::before { content: '\e877'; } + +.feather-grid::before { content: '\e878'; } + +.feather-heart::before { content: '\e879'; } + +.feather-home::before { content: '\e87a'; } + +.feather-github::before { content: '\e87b'; } + +.feather-image::before { content: '\e87c'; } + +.feather-inbox::before { content: '\e87d'; } + +.feather-layers::before { content: '\e87e'; } + +.feather-info::before { content: '\e87f'; } + +.feather-instagram::before { content: '\e880'; } + +.feather-layout::before { content: '\e881'; } + +.feather-link-2::before { content: '\e882'; } + +.feather-life-buoy::before { content: '\e883'; } + +.feather-link::before { content: '\e884'; } + +.feather-log-in::before { content: '\e885'; } + +.feather-list::before { content: '\e886'; } + +.feather-lock::before { content: '\e887'; } + +.feather-log-out::before { content: '\e888'; } + +.feather-loader::before { content: '\e889'; } + +.feather-mail::before { content: '\e88a'; } + +.feather-maximize-2::before { content: '\e88b'; } + +.feather-map::before { content: '\e88c'; } + +.feather-map-pin::before { content: '\e88e'; } + +.feather-menu::before { content: '\e88f'; } + +.feather-message-circle::before { content: '\e890'; } + +.feather-message-square::before { content: '\e891'; } + +.feather-minimize-2::before { content: '\e892'; } + +.feather-mic-off::before { content: '\e893'; } + +.feather-minus-circle::before { content: '\e894'; } + +.feather-mic::before { content: '\e895'; } + +.feather-minus-square::before { content: '\e896'; } + +.feather-minus::before { content: '\e897'; } + +.feather-moon::before { content: '\e898'; } + +.feather-monitor::before { content: '\e899'; } + +.feather-more-vertical::before { content: '\e89a'; } + +.feather-more-horizontal::before { content: '\e89b'; } + +.feather-move::before { content: '\e89c'; } + +.feather-music::before { content: '\e89d'; } + +.feather-navigation-2::before { content: '\e89e'; } + +.feather-navigation::before { content: '\e89f'; } + +.feather-octagon::before { content: '\e8a0'; } + +.feather-package::before { content: '\e8a1'; } + +.feather-pause-circle::before { content: '\e8a2'; } + +.feather-pause::before { content: '\e8a3'; } + +.feather-percent::before { content: '\e8a4'; } + +.feather-phone-call::before { content: '\e8a5'; } + +.feather-phone-forwarded::before { content: '\e8a6'; } + +.feather-phone-missed::before { content: '\e8a7'; } + +.feather-phone-off::before { content: '\e8a8'; } + +.feather-phone-incoming::before { content: '\e8a9'; } + +.feather-phone::before { content: '\e8aa'; } + +.feather-phone-outgoing::before { content: '\e8ab'; } + +.feather-pie-chart::before { content: '\e8ac'; } + +.feather-play-circle::before { content: '\e8ad'; } + +.feather-play::before { content: '\e8ae'; } + +.feather-plus-square::before { content: '\e8af'; } + +.feather-plus-circle::before { content: '\e8b0'; } + +.feather-plus::before { content: '\e8b1'; } + +.feather-pocket::before { content: '\e8b2'; } + +.feather-printer::before { content: '\e8b3'; } + +.feather-power::before { content: '\e8b4'; } + +.feather-radio::before { content: '\e8b5'; } + +.feather-repeat::before { content: '\e8b6'; } + +.feather-refresh-ccw::before { content: '\e8b7'; } + +.feather-rewind::before { content: '\e8b8'; } + +.feather-rotate-ccw::before { content: '\e8b9'; } + +.feather-refresh-cw::before { content: '\e8ba'; } + +.feather-rotate-cw::before { content: '\e8bb'; } + +.feather-save::before { content: '\e8bc'; } + +.feather-search::before { content: '\e8bd'; } + +.feather-server::before { content: '\e8be'; } + +.feather-scissors::before { content: '\e8bf'; } + +.feather-share-2::before { content: '\e8c0'; } + +.feather-share::before { content: '\e8c1'; } + +.feather-shield::before { content: '\e8c2'; } + +.feather-settings::before { content: '\e8c3'; } + +.feather-skip-back::before { content: '\e8c4'; } + +.feather-shuffle::before { content: '\e8c5'; } + +.feather-sidebar::before { content: '\e8c6'; } + +.feather-skip-forward::before { content: '\e8c7'; } + +.feather-slack::before { content: '\e8c8'; } + +.feather-slash::before { content: '\e8c9'; } + +.feather-smartphone::before { content: '\e8ca'; } + +.feather-square::before { content: '\e8cb'; } + +.feather-speaker::before { content: '\e8cc'; } + +.feather-star::before { content: '\e8cd'; } + +.feather-stop-circle::before { content: '\e8ce'; } + +.feather-sun::before { content: '\e8cf'; } + +.feather-sunrise::before { content: '\e8d0'; } + +.feather-tablet::before { content: '\e8d1'; } + +.feather-tag::before { content: '\e8d2'; } + +.feather-sunset::before { content: '\e8d3'; } + +.feather-target::before { content: '\e8d4'; } + +.feather-thermometer::before { content: '\e8d5'; } + +.feather-thumbs-up::before { content: '\e8d6'; } + +.feather-thumbs-down::before { content: '\e8d7'; } + +.feather-toggle-left::before { content: '\e8d8'; } + +.feather-toggle-right::before { content: '\e8d9'; } + +.feather-trash-2::before { content: '\e8da'; } + +.feather-trash::before { content: '\e8db'; } + +.feather-trending-up::before { content: '\e8dc'; } + +.feather-trending-down::before { content: '\e8dd'; } + +.feather-triangle::before { content: '\e8de'; } + +.feather-type::before { content: '\e8df'; } + +.feather-twitter::before { content: '\e8e0'; } + +.feather-upload::before { content: '\e8e1'; } + +.feather-umbrella::before { content: '\e8e2'; } + +.feather-upload-cloud::before { content: '\e8e3'; } + +.feather-unlock::before { content: '\e8e4'; } + +.feather-user-check::before { content: '\e8e5'; } + +.feather-user-minus::before { content: '\e8e6'; } + +.feather-user-plus::before { content: '\e8e7'; } + +.feather-user-x::before { content: '\e8e8'; } + +.feather-user::before { content: '\e8e9'; } + +.feather-users::before { content: '\e8ea'; } + +.feather-video-off::before { content: '\e8eb'; } + +.feather-video::before { content: '\e8ec'; } + +.feather-voicemail::before { content: '\e8ed'; } + +.feather-volume-x::before { content: '\e8ee'; } + +.feather-volume-2::before { content: '\e8ef'; } + +.feather-volume-1::before { content: '\e8f0'; } + +.feather-volume::before { content: '\e8f1'; } + +.feather-watch::before { content: '\e8f2'; } + +.feather-wifi::before { content: '\e8f3'; } + +.feather-x-square::before { content: '\e8f4'; } + +.feather-wind::before { content: '\e8f5'; } + +.feather-x::before { content: '\e8f6'; } + +.feather-x-circle::before { content: '\e8f7'; } + +.feather-zap::before { content: '\e8f8'; } + +.feather-zoom-in::before { content: '\e8f9'; } + +.feather-zoom-out::before { content: '\e8fa'; } + +.feather-command::before { content: '\e8fb'; } + +.feather-cloud::before { content: '\e8fc'; } + +.feather-hash::before { content: '\e8fd'; } + +.feather-headphones::before { content: '\e8fe'; } + +.feather-underline::before { content: '\e8ff'; } + +.feather-italic::before { content: '\e900'; } + +.feather-bold::before { content: '\e901'; } + +.feather-crop::before { content: '\e902'; } + +.feather-help-circle::before { content: '\e903'; } + +.feather-paperclip::before { content: '\e904'; } + +.feather-shopping-cart::before { content: '\e905'; } + +.feather-tv::before { content: '\e906'; } + +.feather-wifi-off::before { content: '\e907'; } + +.feather-minimize::before { content: '\e88d'; } + +.feather-maximize::before { content: '\e908'; } + +.feather-gitlab::before { content: '\e909'; } + +.feather-sliders::before { content: '\e90a'; } + +.feather-star-on::before { content: '\e90b'; } + +.feather-heart-on::before { content: '\e90c'; } + +.feather-archive::before { content: '\e90d'; } + +.feather-arrow-down-circle::before { content: '\e90e'; } + +.feather-arrow-up-circle::before { content: '\e90f'; } + +.feather-arrow-left-circle::before { content: '\e910'; } + +.feather-arrow-right-circle::before { content: '\e911'; } + +.feather-bar-chart-line-::before { content: '\e912'; } + +.feather-bar-chart-line::before { content: '\e913'; } + +.feather-book-open::before { content: '\e914'; } + +.feather-code::before { content: '\e915'; } + +.feather-database::before { content: '\e916'; } + +.feather-dollar-sign::before { content: '\e917'; } + +.feather-folder-plus::before { content: '\e918'; } + +.feather-gift::before { content: '\e919'; } + +.feather-folder-minus::before { content: '\e91a'; } + +.feather-git-commit::before { content: '\e91b'; } + +.feather-git-branch::before { content: '\e91c'; } + +.feather-git-pull-request::before { content: '\e91d'; } + +.feather-git-merge::before { content: '\e91e'; } + +.feather-linkedin::before { content: '\e91f'; } + +.feather-hard-drive::before { content: '\e920'; } + +.feather-more-vertical-::before { content: '\e921'; } + +.feather-more-horizontal-::before { content: '\e922'; } + +.feather-rss::before { content: '\e923'; } + +.feather-send::before { content: '\e924'; } + +.feather-shield-off::before { content: '\e925'; } + +.feather-shopping-bag::before { content: '\e926'; } + +.feather-terminal::before { content: '\e927'; } + +.feather-truck::before { content: '\e928'; } + +.feather-zap-off::before { content: '\e929'; } + +.feather-youtube::before { content: '\e92a'; } diff --git a/docs/assets/fonts/feather/feather.eot b/docs/assets/fonts/feather/feather.eot deleted file mode 100755 index 58371d908585297e19aae091f772f66c9d9d590d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62084 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 diff --git a/docs/assets/fonts/feather/feather.svg b/docs/assets/fonts/feather/feather.svg deleted file mode 100755 index 5dda143b66..0000000000 --- a/docs/assets/fonts/feather/feather.svg +++ /dev/null @@ -1,849 +0,0 @@ - - - - - -Created by iconfont - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/assets/fonts/feather/feather.ttf b/docs/assets/fonts/feather/feather.ttf deleted file mode 100755 index 0b33dac7826e8cfc7ee0337f00078bd9aea7f5c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61920 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
List of users.
List of orders.
List of transactions.
eS(#SdEX(%hjf6_p28iet8 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 diff --git a/docs/assets/fonts/feather/feather.svg b/docs/assets/fonts/feather/feather.svg deleted file mode 100755 index 5dda143b66..0000000000 --- a/docs/assets/fonts/feather/feather.svg +++ /dev/null @@ -1,849 +0,0 @@ - - - - - -Created by iconfont - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/assets/fonts/feather/feather.ttf b/docs/assets/fonts/feather/feather.ttf deleted file mode 100755 index 0b33dac7826e8cfc7ee0337f00078bd9aea7f5c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61920 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
Y& zuU;*ePh~T8OBXFM&TP^$TF!h&{=h&>q0nE~pUV!_ZN$s8bUIr%oXhUh5`{&Bg~IU4 z#f$kz`23uh(JZnIil>H=q<1m?nIkdpUnE92#9$@lGkm-G;Oze> zL<(rGmEb@Q)w&au*-aku!oAWDyJ{5$aYvX?T?`thD8dq_(+s)@F`8_SnoV_7PjhH4 z&4X`SBZ6-)2LH1Ftja=)0hKMLCA5@Us1*!FJ1s+b!%Judt%QPPH3apwP&ReaI_jcs zT2C8jBcad$T}qeH<+O#apsjQzU4;U{+i3^wgz2@HcG1GwC>Zbu3q!jI={gkF5%21Yu=?2PCo(fc?12jUTbdV0g|KTROnQoz5A(-DrAEw*s zFX$t52i-}B=`Q*xeT=~MIw9j8a>)ASg9 z1{qu)rzhxh^m+OMJqdHv2^y#WL0_V$z#KeHe@TBu|C9cjo}s^?XX!cm3O!F>r5ETV zeT}|OFVZ*Yf6+JTTl8)E4*f0t9sO^5iM~rO)BmCG(cjbe=?C-=^pErkH2kONpXi_I zhx8+Qm3~bBLa)*PrGKT@=_mA4`WgM4-k@L5FX`Xt-|0=r{J*B((0|Zx=`H$CBpm!5 z{ht0m{ej-5cj&+9kMu5;NT*3?yhu?LRj~qJ*%gQ4R9uQ%@hD!!hXmmPrAi4ZAth{~ zQC~c*$K({-#DQ@te?u{z)2w(|fzKSs zWiw)`$_G3RKJ$v42=k~oY+lHVXZ*&6d`#TuDIZqe$nUeuj<^!()No%GlVnc}0uyVt zL^_+;AHZiZ8N<>J7BZLV+R6|yUjav_BwxMD^mGETZ2T}v^0{D=ad#dd)(4J#Bp4g9$dWYl1yxCow zIB)2sjwVYG?(=a4yA2*fyLU!DlX>Ol9pk?7n!x zlhgWhT7EE=NQ~grNGg+b=duNGU3|t}zB=ME&yHC0@dKJY4;V@e;wy)Fb>JDgb8AlP_e4O+d&OGYN0brvi5EIE4=2Om09c zc$obh0^nmdT!8$czI?1WjI*M}JJ(al4uE(GGT}Aa0w355Idmvy6JMS}4wxH*!qdKT zo1b@@_woD#C|tmis=r}zHACWc8RlM zF-2?C%3n7A$h!_;`m($wY@+2lkWD2t-fhkU*>rJ8i;X&rhIwMCU7oOw#0!Z*>qx3U zka`Fk^-wlD6ia2C;v4YDNO~xqNiyOuCar_KNWdpau||1UF@p^c zq@dYT*jlLss9!p11>PL?3~Fg}tz5%QxtW&u@`Kr7Ac6r#umz=Xz{y?WAvrO8vG1KG z=3r!%j`un8X$(7;cQ6FRvKgm9XJ|MWB2x#npd{zK8pcQrh602@j?B12&fD_<}?!?o8>>{=%7M<^LFuE`HX%@?W1B>FUr~m)} diff --git a/docs/assets/fonts/feather/feather.svg b/docs/assets/fonts/feather/feather.svg deleted file mode 100755 index 5dda143b66..0000000000 --- a/docs/assets/fonts/feather/feather.svg +++ /dev/null @@ -1,849 +0,0 @@ - - - - - -Created by iconfont - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/assets/fonts/feather/feather.ttf b/docs/assets/fonts/feather/feather.ttf deleted file mode 100755 index 0b33dac7826e8cfc7ee0337f00078bd9aea7f5c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61920 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