feat: RTL support (#1634)

This commit is contained in:
Sergey Andrievskiy 2018-05-11 17:25:02 +03:00 committed by Dmitry Nehaychik
parent 06d2197583
commit 3b63759e84
40 changed files with 660 additions and 196 deletions

100
package-lock.json generated
View file

@ -690,19 +690,19 @@
} }
}, },
"@nebular/auth": { "@nebular/auth": {
"version": "2.0.0-rc.7", "version": "2.0.0-rc.8",
"resolved": "https://registry.npmjs.org/@nebular/auth/-/auth-2.0.0-rc.7.tgz", "resolved": "https://registry.npmjs.org/@nebular/auth/-/auth-2.0.0-rc.8.tgz",
"integrity": "sha512-0REoqU771vKuF02bnBZVqDAzC5WfWfB79dl6Wk51Oau6tOJDpL3Kw3FPbPeHHDr3tzFj9UNDXGmtJ0DyUAaibQ==" "integrity": "sha512-uImudGbG2qcaTpimjJFyqRdxhjE62sQfqqzZcH//NsokXbC5+8YMfUMcX4SpPTYOpWsx4p9T4vEIUDJOoYIBnw=="
}, },
"@nebular/security": { "@nebular/security": {
"version": "2.0.0-rc.7", "version": "2.0.0-rc.8",
"resolved": "https://registry.npmjs.org/@nebular/security/-/security-2.0.0-rc.7.tgz", "resolved": "https://registry.npmjs.org/@nebular/security/-/security-2.0.0-rc.8.tgz",
"integrity": "sha512-K2VOvgUUzd54v7VSs6pFfzdq0UhRlYhCP4EPCi3INcM7mY/dh6F6yIDZMlz0AybS5et1G4PMWUHqvUi1AnrSsQ==" "integrity": "sha512-aC3q1AR7jmF3Cm/TNT4Rut/ZQcmBrna0zNPxwg5cBSvWAPk3vRXVTYSFPQCNHDs2tyXJz4Xf50Sl2YJQhCiMnw=="
}, },
"@nebular/theme": { "@nebular/theme": {
"version": "2.0.0-rc.7", "version": "2.0.0-rc.8",
"resolved": "https://registry.npmjs.org/@nebular/theme/-/theme-2.0.0-rc.7.tgz", "resolved": "https://registry.npmjs.org/@nebular/theme/-/theme-2.0.0-rc.8.tgz",
"integrity": "sha512-I8hB+ik/1086HSx8tbJcHuZfXdfpq5lg8cDcUMW0h8Y3Gp0Na5sqpdq850SoTlcqc4HiE6CFS/fkx6ro+8HtTQ==" "integrity": "sha512-1BLG4J0ElUOHMjIJQ6lSSzMK+8iaPX1brDVPI3Ol0O0FTiyCPVXugyK09/GNX2Of4xUIZqX7VvNYGywiJ7dUTw=="
}, },
"@ng-bootstrap/ng-bootstrap": { "@ng-bootstrap/ng-bootstrap": {
"version": "1.0.0", "version": "1.0.0",
@ -3106,16 +3106,6 @@
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true "dev": true
}, },
"cors": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz",
"integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=",
"dev": true,
"requires": {
"object-assign": "^4",
"vary": "^1"
}
},
"cosmiconfig": { "cosmiconfig": {
"version": "2.2.2", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
@ -3584,7 +3574,6 @@
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": { "requires": {
"ms": "2.0.0" "ms": "2.0.0"
} }
@ -3747,8 +3736,7 @@
"depd": { "depd": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
"dev": true
}, },
"des.js": { "des.js": {
"version": "1.0.0", "version": "1.0.0",
@ -3763,8 +3751,7 @@
"destroy": { "destroy": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
"dev": true
}, },
"detect-indent": { "detect-indent": {
"version": "4.0.0", "version": "4.0.0",
@ -4186,8 +4173,7 @@
"ee-first": { "ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
"dev": true
}, },
"ejs": { "ejs": {
"version": "2.6.1", "version": "2.6.1",
@ -4225,8 +4211,7 @@
"encodeurl": { "encodeurl": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
"dev": true
}, },
"end-of-stream": { "end-of-stream": {
"version": "1.4.1", "version": "1.4.1",
@ -4429,8 +4414,7 @@
"escape-html": { "escape-html": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
"dev": true
}, },
"escape-string-regexp": { "escape-string-regexp": {
"version": "1.0.5", "version": "1.0.5",
@ -4525,8 +4509,7 @@
"etag": { "etag": {
"version": "1.8.1", "version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
"dev": true
}, },
"event-stream": { "event-stream": {
"version": "3.3.4", "version": "3.3.4",
@ -5099,8 +5082,7 @@
"fresh": { "fresh": {
"version": "0.5.2", "version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
"dev": true
}, },
"from": { "from": {
"version": "0.1.7", "version": "0.1.7",
@ -7122,7 +7104,6 @@
"version": "1.6.2", "version": "1.6.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
"integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
"dev": true,
"requires": { "requires": {
"depd": "1.1.1", "depd": "1.1.1",
"inherits": "2.0.3", "inherits": "2.0.3",
@ -7133,14 +7114,12 @@
"depd": { "depd": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
"dev": true
}, },
"setprototypeof": { "setprototypeof": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
"integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
"dev": true
} }
} }
}, },
@ -7639,8 +7618,7 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
"dev": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -8039,8 +8017,7 @@
"is-wsl": { "is-wsl": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
"integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0="
"dev": true
}, },
"isarray": { "isarray": {
"version": "1.0.0", "version": "1.0.0",
@ -8996,17 +8973,10 @@
"integrity": "sha1-pp8ObKWB4DkapXlBlw4XwwjdSGk=", "integrity": "sha1-pp8ObKWB4DkapXlBlw4XwwjdSGk=",
"dev": true, "dev": true,
"requires": { "requires": {
"colors": "latest",
"connect": "3.4.x", "connect": "3.4.x",
"cors": "latest",
"event-stream": "latest",
"faye-websocket": "0.11.x", "faye-websocket": "0.11.x",
"http-auth": "2.4.x", "http-auth": "2.4.x",
"morgan": "^1.6.1", "morgan": "^1.6.1",
"object-assign": "latest",
"opn": "latest",
"proxy-middleware": "latest",
"send": "latest",
"serve-index": "^1.7.2", "serve-index": "^1.7.2",
"watchr": "2.6.x" "watchr": "2.6.x"
}, },
@ -9014,8 +8984,7 @@
"colors": { "colors": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
"integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM="
"dev": true
}, },
"faye-websocket": { "faye-websocket": {
"version": "0.11.1", "version": "0.11.1",
@ -9029,20 +8998,17 @@
"mime": { "mime": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
"dev": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
"dev": true
}, },
"opn": { "opn": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz", "resolved": "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz",
"integrity": "sha512-Jd/GpzPyHF4P2/aNOVmS3lfMSWV9J7cOhCG1s08XCEAsPkB7lp6ddiU0J7XzyQRDUh8BqJ7PchfINjR8jyofRQ==", "integrity": "sha512-Jd/GpzPyHF4P2/aNOVmS3lfMSWV9J7cOhCG1s08XCEAsPkB7lp6ddiU0J7XzyQRDUh8BqJ7PchfINjR8jyofRQ==",
"dev": true,
"requires": { "requires": {
"is-wsl": "^1.1.0" "is-wsl": "^1.1.0"
} }
@ -9051,7 +9017,6 @@
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
"integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
"dev": true,
"requires": { "requires": {
"debug": "2.6.9", "debug": "2.6.9",
"depd": "~1.1.2", "depd": "~1.1.2",
@ -9071,8 +9036,7 @@
"statuses": { "statuses": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
"dev": true
} }
} }
}, },
@ -9758,8 +9722,7 @@
"ms": { "ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
"dev": true
}, },
"multicast-dns": { "multicast-dns": {
"version": "6.2.3", "version": "6.2.3",
@ -10444,7 +10407,6 @@
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"dev": true,
"requires": { "requires": {
"ee-first": "1.1.1" "ee-first": "1.1.1"
} }
@ -11440,12 +11402,6 @@
"ipaddr.js": "1.6.0" "ipaddr.js": "1.6.0"
} }
}, },
"proxy-middleware": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz",
"integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY=",
"dev": true
},
"prr": { "prr": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@ -11612,8 +11568,7 @@
"range-parser": { "range-parser": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
"dev": true
}, },
"raw-body": { "raw-body": {
"version": "2.3.2", "version": "2.3.2",
@ -12965,8 +12920,7 @@
"statuses": { "statuses": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
"dev": true
}, },
"stdout-stream": { "stdout-stream": {
"version": "1.4.0", "version": "1.4.0",

View file

@ -40,9 +40,9 @@
"@angular/platform-browser-dynamic": "6.0.0", "@angular/platform-browser-dynamic": "6.0.0",
"@angular/router": "6.0.0", "@angular/router": "6.0.0",
"@asymmetrik/ngx-leaflet": "3.0.1", "@asymmetrik/ngx-leaflet": "3.0.1",
"@nebular/auth": "^2.0.0-rc.7", "@nebular/auth": "^2.0.0-rc.8",
"@nebular/security": "^2.0.0-rc.7", "@nebular/security": "^2.0.0-rc.8",
"@nebular/theme": "^2.0.0-rc.7", "@nebular/theme": "^2.0.0-rc.8",
"@ng-bootstrap/ng-bootstrap": "1.0.0", "@ng-bootstrap/ng-bootstrap": "1.0.0",
"@swimlane/ngx-charts": "7.0.1", "@swimlane/ngx-charts": "7.0.1",
"angular2-chartjs": "0.4.1", "angular2-chartjs": "0.4.1",

View file

@ -1,10 +1,11 @@
import { Injectable, OnDestroy } from '@angular/core';
import { of as observableOf, Observable, BehaviorSubject } from 'rxjs';
import { takeWhile } from 'rxjs/operators';
import { of as observableOf, Observable , BehaviorSubject } from 'rxjs'; import { NbLayoutDirectionService, NbLayoutDirection } from '@nebular/theme';
import { Injectable } from '@angular/core';
@Injectable() @Injectable()
export class StateService { export class StateService implements OnDestroy {
protected layouts: any = [ protected layouts: any = [
{ {
@ -27,21 +28,44 @@ export class StateService {
protected sidebars: any = [ protected sidebars: any = [
{ {
name: 'Left Sidebar', name: 'Sidebar at layout start',
icon: 'nb-layout-sidebar-left', icon: 'nb-layout-sidebar-left',
id: 'left', id: 'start',
selected: true, selected: true,
}, },
{ {
name: 'Right Sidebar', name: 'Sidebar at layout end',
icon: 'nb-layout-sidebar-right', icon: 'nb-layout-sidebar-right',
id: 'right', id: 'end',
}, },
]; ];
protected layoutState$ = new BehaviorSubject(this.layouts[0]); protected layoutState$ = new BehaviorSubject(this.layouts[0]);
protected sidebarState$ = new BehaviorSubject(this.sidebars[0]); protected sidebarState$ = new BehaviorSubject(this.sidebars[0]);
alive = true;
constructor(directionService: NbLayoutDirectionService) {
directionService.onDirectionChange()
.pipe(takeWhile(() => this.alive))
.subscribe(direction => this.updateSidebarIcons(direction));
this.updateSidebarIcons(directionService.getDirection());
}
ngOnDestroy() {
this.alive = false;
}
private updateSidebarIcons(direction: NbLayoutDirection) {
const [ startSidebar, endSidebar ] = this.sidebars;
const isLtr = direction === NbLayoutDirection.LTR;
const startIconClass = isLtr ? 'nb-layout-sidebar-left' : 'nb-layout-sidebar-right';
const endIconClass = isLtr ? 'nb-layout-sidebar-right' : 'nb-layout-sidebar-left';
startSidebar.icon = startIconClass;
endSidebar.icon = endIconClass;
}
setLayoutState(state: any): any { setLayoutState(state: any): any {
this.layoutState$.next(state); this.layoutState$.next(state);
} }

View file

@ -6,6 +6,7 @@
<div class="logo" (click)="goToHome()">ngx-<span>admin</span></div> <div class="logo" (click)="goToHome()">ngx-<span>admin</span></div>
</div> </div>
<ngx-theme-switcher></ngx-theme-switcher> <ngx-theme-switcher></ngx-theme-switcher>
<ngx-layout-direction-switcher></ngx-layout-direction-switcher>
</div> </div>
<nb-actions <nb-actions
@ -13,7 +14,7 @@
class="header-container" class="header-container"
[class.right]="position === 'normal'" [class.right]="position === 'normal'"
[class.left]="position === 'inverse'"> [class.left]="position === 'inverse'">
<nb-action icon="nb-grid-b" class="toggle-layout" (click)="toggleSettings()"></nb-action> <nb-action icon="nb-gear" class="toggle-layout" (click)="toggleSettings()"></nb-action>
<nb-action *nbIsGranted="['view', 'user']" > <nb-action *nbIsGranted="['view', 'user']" >
<nb-user [nbContextMenu]="userMenu" [name]="user?.name" [picture]="user?.picture"></nb-user> <nb-user [nbContextMenu]="userMenu" [name]="user?.name" [picture]="user?.picture"></nb-user>
</nb-action> </nb-action>

View file

@ -33,7 +33,8 @@
width: 100%; width: 100%;
.navigation { .navigation {
padding-right: nb-theme(padding); @include nb-ltr(padding-right, nb-theme(padding));
@include nb-rtl(padding-left, nb-theme(padding));
font-size: 2.5rem; font-size: 2.5rem;
text-decoration: none; text-decoration: none;
@ -47,7 +48,8 @@
padding: 0 nb-theme(padding); padding: 0 nb-theme(padding);
font-size: 1.75rem; font-size: 1.75rem;
font-weight: nb-theme(font-weight-bolder); font-weight: nb-theme(font-weight-bolder);
border-left: 1px solid nb-theme(separator); @include nb-ltr(border-left, 1px solid nb-theme(separator));
@include nb-rtl(border-right, 1px solid nb-theme(separator));
white-space: nowrap; white-space: nowrap;
span { span {
@ -56,6 +58,17 @@
} }
} }
ngx-layout-direction-switcher,
ngx-theme-switcher {
margin: 0 1em;
}
@include media-breakpoint-down(xl) {
ngx-layout-direction-switcher {
display: none;
}
}
.toggle-layout /deep/ a { .toggle-layout /deep/ a {
display: block; display: block;
text-decoration: none; text-decoration: none;
@ -64,6 +77,54 @@
i { i {
color: nb-theme(color-fg-highlight); color: nb-theme(color-fg-highlight);
font-size: 2.25rem; font-size: 2.25rem;
border-radius: 50%;
position: relative;
animation-name: pulse-light;
&::after {
content: ' ';
// hack to be able to set border-radius
background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
border-radius: 50%;
pointer-events: none;
position: absolute;
top: 52.3%;
left: 50%;
transform: translate(-50%, -50%);
width: 13%;
height: 13%;
animation: 3s linear infinite pulse;
@include nb-for-theme(default) {
animation-name: pulse-light;
}
}
}
}
@include keyframes(pulse) {
0% {
box-shadow: 0 0 1px 0 rgba(nb-theme(color-fg-highlight), 0);
}
20% {
box-shadow: 0 0 3px 10px rgba(nb-theme(color-fg-highlight), 0.4);
}
100% {
box-shadow: 0 0 5px 20px rgba(nb-theme(color-fg-highlight), 0);
}
}
@include keyframes(pulse-light) {
0% {
box-shadow: 0 0 1px 0 rgba(115, 255, 208, 0);
}
20% {
box-shadow: 0 0 3px 10px rgba(115, 255, 208, 0.4);
}
100% {
box-shadow: 0 0 5px 20px rgba(115, 255, 208, 0);
} }
} }
@ -80,6 +141,11 @@
.toggle-layout { .toggle-layout {
padding: 0; padding: 0;
} }
ngx-layout-direction-switcher,
ngx-theme-switcher {
display: none;
}
} }
@include media-breakpoint-down(sm) { @include media-breakpoint-down(sm) {
@ -112,4 +178,3 @@
} }
} }
} }

View file

@ -4,3 +4,5 @@ export * from './search-input/search-input.component';
export * from './tiny-mce/tiny-mce.component'; export * from './tiny-mce/tiny-mce.component';
export * from './theme-settings/theme-settings.component'; export * from './theme-settings/theme-settings.component';
export * from './theme-switcher/theme-switcher.component'; export * from './theme-switcher/theme-switcher.component';
export * from './switcher/switcher.component';
export * from './layout-direction-switcher/layout-direction-switcher.component'

View file

@ -0,0 +1,42 @@
import { Component, OnDestroy, Input } from '@angular/core';
import { NbLayoutDirectionService, NbLayoutDirection } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators/takeWhile';
@Component({
selector: 'ngx-layout-direction-switcher',
template: `
<ngx-switcher
[firstValue]="directions.RTL"
[secondValue]="directions.LTR"
[firstValueLabel]="'RTL'"
[secondValueLabel]="'LTR'"
[value]="currentDirection"
(valueChange)="toggleDirection($event)"
[vertical]="vertical"
>
</ngx-switcher>
`,
})
export class LayoutDirectionSwitcherComponent implements OnDestroy {
directions = NbLayoutDirection;
currentDirection: NbLayoutDirection;
alive = true;
@Input() vertical: boolean = false;
constructor(private directionService: NbLayoutDirectionService) {
this.currentDirection = this.directionService.getDirection();
this.directionService.onDirectionChange()
.pipe(takeWhile(() => this.alive))
.subscribe(newDirection => this.currentDirection = newDirection);
}
toggleDirection(newDirection) {
this.directionService.setDirection(newDirection);
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -4,39 +4,51 @@
@import '~@nebular/theme/styles/global/bootstrap/breakpoints'; @import '~@nebular/theme/styles/global/bootstrap/breakpoints';
@include nb-install-component() { @include nb-install-component() {
display: flex; .switch-label {
flex-direction: column;
align-items: center;
width: 50%;
.theme-switch {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
margin: 0; margin: 0;
&.vertical {
flex-direction: column;
align-items: flex-start;
.first,
.second {
padding: 0;
}
.switch {
margin-top: 0.5em;
}
}
& > span { & > span {
font-size: 1.125rem; font-size: 1.125rem;
font-weight: nb-theme(font-weight-bold); font-weight: nb-theme(font-weight-bold);
transition: opacity 0.3s ease; transition: opacity 0.3s ease;
color: nb-theme(color-fg);
&.light { &.first {
color: nb-theme(color-fg-text); @include nb-ltr(padding-right, 10px);
padding-right: 10px; @include nb-rtl(padding-left, 10px);
} }
&.cosmic { &.second {
color: nb-theme(color-fg); @include nb-ltr(padding-left, 10px);
padding-left: 10px; @include nb-rtl(padding-right, 10px);
}
&.active {
color: nb-theme(color-fg-text);
} }
@include nb-for-theme(cosmic) { @include nb-for-theme(cosmic) {
&.light { color: nb-theme(color-fg);
color: nb-theme(color-fg);
}
&.cosmic { &.active {
color: nb-theme(color-white); color: nb-theme(color-white);
} }
} }
@ -58,7 +70,8 @@
display: none; display: none;
&:checked + .slider::before { &:checked + .slider::before {
transform: translateX(2.25rem); @include nb-ltr(transform, translateX(2.25rem));
@include nb-rtl(transform, translateX(-2.25rem));
} }
} }
@ -89,13 +102,7 @@
} }
} }
@include media-breakpoint-down(is) {
.light, .cosmic {
display: none;
}
}
@include media-breakpoint-down(xs) { @include media-breakpoint-down(xs) {
align-items: flex-end; align-items: flex-end;
} }
} }

View file

@ -0,0 +1,60 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'ngx-switcher',
styleUrls: ['./switcher.component.scss'],
template: `
<label class="switch-label" [class.vertical]="vertical">
<span class="first" [class.active]="vertical || isFirstValue()">
{{vertical ? currentValueLabel() : firstValueLabel}}
</span>
<div class="switch">
<input type="checkbox" [checked]="isSecondValue()" (change)="changeValue()">
<span class="slider"></span>
</div>
<span
*ngIf="!vertical"
class="second"
[class.active]="isSecondValue()"
>
{{secondValueLabel}}
</span>
</label>
`,
})
export class SwitcherComponent {
@Input() firstValue: any;
@Input() secondValue: any;
@Input() firstValueLabel: string;
@Input() secondValueLabel: string;
@Input() vertical: boolean;
@Input() value: any;
@Output() valueChange = new EventEmitter<any>();
isFirstValue() {
return this.value === this.firstValue;
}
isSecondValue() {
return this.value === this.secondValue;
}
currentValueLabel() {
return this.isFirstValue()
? this.firstValueLabel
: this.secondValueLabel;
}
changeValue() {
this.value = this.isFirstValue()
? this.secondValue
: this.firstValue;
this.valueChange.emit(this.value);
}
}

View file

@ -32,5 +32,40 @@
} }
} }
} }
}
.settings {
margin-bottom: 1em;
}
.switcher {
margin-bottom: 1rem;
/deep/ ngx-switcher {
.switch-label span {
font-size: 1em;
font-weight: normal;
}
.switch {
height: 1.5em;
width: 3em;
.slider::before {
height: 1.5em;
width: 1.5em;
}
input:checked + .slider::before {
@include nb-ltr(transform, translateX(1.5rem)!important);
@include nb-rtl(transform, translateX(-1.5rem)!important);
}
}
@include nb-for-theme(cosmic) {
.switch .slider {
background-color: nb-theme(color-bg);
}
}
}
}
}

View file

@ -26,6 +26,13 @@ import { StateService } from '../../../@core/data/state.service';
<i [attr.class]="sidebar.icon"></i> <i [attr.class]="sidebar.icon"></i>
</a> </a>
</div> </div>
<h6 class="settings">SETTINGS</h6>
<div class="switcher">
<ngx-theme-switcher [vertical]="true"></ngx-theme-switcher>
</div>
<div class="switcher">
<ngx-layout-direction-switcher [vertical]="true"></ngx-layout-direction-switcher>
</div>
`, `,
}) })
export class ThemeSettingsComponent { export class ThemeSettingsComponent {

View file

@ -1,27 +1,35 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit, Input } from '@angular/core';
import { NbThemeService } from '@nebular/theme'; import { NbThemeService } from '@nebular/theme';
import { NbJSThemeOptions } from '@nebular/theme/services/js-themes/theme.options'; import { NbJSThemeOptions } from '@nebular/theme/services/js-themes/theme.options';
import { AnalyticsService } from '../../../@core/utils/analytics.service'; import { AnalyticsService } from '../../../@core/utils/analytics.service';
@Component({ @Component({
selector: 'ngx-theme-switcher', selector: 'ngx-theme-switcher',
styleUrls: ['./theme-switcher.component.scss'],
template: ` template: `
<label class="theme-switch"> <ngx-switcher
<span class="light">Light</span> [firstValue]="false"
<div class="switch"> [secondValue]="true"
<input type="checkbox" [checked]="currentBoolTheme()" (change)="toggleTheme(theme.checked)" #theme> [firstValueLabel]="'Light'"
<span class="slider"></span> [secondValueLabel]="'Cosmic'"
</div> [value]="currentBoolTheme()"
<span class="cosmic">Cosmic</span> (valueChange)="toggleTheme($event)"
</label> [vertical]="vertical"
>
</ngx-switcher>
`, `,
}) })
export class ThemeSwitcherComponent implements OnInit { export class ThemeSwitcherComponent implements OnInit {
theme: NbJSThemeOptions; theme: NbJSThemeOptions;
constructor(private themeService: NbThemeService, private analyticsService: AnalyticsService) { firstTheme = 'default';
} secondTheme = 'cosmic';
@Input() vertical: boolean = false;
constructor(
private themeService: NbThemeService,
private analyticsService: AnalyticsService,
) {}
ngOnInit() { ngOnInit() {
this.themeService.getJsTheme() this.themeService.getJsTheme()
@ -29,8 +37,9 @@ export class ThemeSwitcherComponent implements OnInit {
} }
toggleTheme(theme: boolean) { toggleTheme(theme: boolean) {
const boolTheme = this.boolToTheme(theme); const themeName = this.boolToTheme(theme);
this.themeService.changeTheme(boolTheme); this.themeService.changeTheme(themeName);
this.analyticsService.trackEvent('switchTheme'); this.analyticsService.trackEvent('switchTheme');
} }
@ -39,10 +48,10 @@ export class ThemeSwitcherComponent implements OnInit {
} }
private themeToBool(theme: NbJSThemeOptions) { private themeToBool(theme: NbJSThemeOptions) {
return theme.name === 'cosmic'; return theme.name === this.secondTheme;
} }
private boolToTheme(theme: boolean) { private boolToTheme(theme: boolean) {
return theme ? 'cosmic' : 'default'; return theme ? this.secondTheme : this.firstTheme;
} }
} }

View file

@ -50,7 +50,8 @@
/deep/ .main-container { /deep/ .main-container {
height: height:
calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important; calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important;
border-top-right-radius: nb-theme(radius); @include nb-ltr(border-top-right-radius, nb-theme(radius));
@include nb-rtl(border-top-left-radius, nb-theme(radius));
} }
/deep/ nb-sidebar-header { /deep/ nb-sidebar-header {
@ -71,7 +72,8 @@
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
} }
span { span {
padding-left: 0.25rem; @include nb-ltr(padding-left, 0.25rem);
@include nb-rtl(padding-right, 0.25rem);
} }
i, span { i, span {
@ -115,7 +117,8 @@
/deep/ .main-container { /deep/ .main-container {
height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important; height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important;
border-top-right-radius: 0; @include nb-ltr(border-top-right-radius, 0);
@include nb-rtl(border-top-left-radius, 0);
.scrollable { .scrollable {
padding-top: 0; padding-top: 0;

View file

@ -50,7 +50,8 @@
/deep/ .main-container { /deep/ .main-container {
height: height:
calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important; calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important;
border-top-right-radius: nb-theme(radius); @include nb-ltr(border-top-right-radius, nb-theme(radius));
@include nb-rtl(border-top-left-radius, nb-theme(radius));
} }
/deep/ nb-sidebar-header { /deep/ nb-sidebar-header {
@ -71,7 +72,8 @@
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
} }
span { span {
padding-left: 0.25rem; @include nb-ltr(padding-left, 0.25rem);
@include nb-rtl(padding-right, 0.25rem);
} }
i, span { i, span {
@ -115,7 +117,8 @@
/deep/ .main-container { /deep/ .main-container {
height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important; height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important;
border-top-right-radius: 0; @include nb-ltr(border-top-right-radius, 0);
@include nb-rtl(border-top-left-radius, 0);
.scrollable { .scrollable {
padding-top: 0; padding-top: 0;

View file

@ -19,13 +19,13 @@ import { StateService } from '../../../@core/data/state.service';
template: ` template: `
<nb-layout [center]="layout.id === 'center-column'" windowMode> <nb-layout [center]="layout.id === 'center-column'" windowMode>
<nb-layout-header fixed> <nb-layout-header fixed>
<ngx-header [position]="sidebar.id === 'left' ? 'normal': 'inverse'"></ngx-header> <ngx-header [position]="sidebar.id === 'start' ? 'normal': 'inverse'"></ngx-header>
</nb-layout-header> </nb-layout-header>
<nb-sidebar class="menu-sidebar" <nb-sidebar class="menu-sidebar"
tag="menu-sidebar" tag="menu-sidebar"
responsive responsive
[right]="sidebar.id === 'right'"> [end]="sidebar.id === 'end'">
<nb-sidebar-header> <nb-sidebar-header>
<a href="#" class="btn btn-hero-success main-btn"> <a href="#" class="btn btn-hero-success main-btn">
<i class="ion ion-social-github"></i> <span>Support Us</span> <i class="ion ion-social-github"></i> <span>Support Us</span>
@ -38,11 +38,11 @@ import { StateService } from '../../../@core/data/state.service';
<ng-content select="router-outlet"></ng-content> <ng-content select="router-outlet"></ng-content>
</nb-layout-column> </nb-layout-column>
<nb-layout-column left class="small" *ngIf="layout.id === 'two-column' || layout.id === 'three-column'"> <nb-layout-column start class="small" *ngIf="layout.id === 'two-column' || layout.id === 'three-column'">
<nb-menu [items]="subMenu"></nb-menu> <nb-menu [items]="subMenu"></nb-menu>
</nb-layout-column> </nb-layout-column>
<nb-layout-column right class="small" *ngIf="layout.id === 'three-column'"> <nb-layout-column class="small" *ngIf="layout.id === 'three-column'">
<nb-menu [items]="subMenu"></nb-menu> <nb-menu [items]="subMenu"></nb-menu>
</nb-layout-column> </nb-layout-column>
@ -51,10 +51,10 @@ import { StateService } from '../../../@core/data/state.service';
</nb-layout-footer> </nb-layout-footer>
<nb-sidebar class="settings-sidebar" <nb-sidebar class="settings-sidebar"
tag="settings-sidebar" tag="settings-sidebar"
state="collapsed" state="collapsed"
fixed fixed
[right]="sidebar.id !== 'right'"> [end]="sidebar.id !== 'end'">
<ngx-theme-settings></ngx-theme-settings> <ngx-theme-settings></ngx-theme-settings>
</nb-sidebar> </nb-sidebar>
</nb-layout> </nb-layout>

View file

@ -50,7 +50,8 @@
/deep/ .main-container { /deep/ .main-container {
height: height:
calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important; calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important;
border-top-right-radius: nb-theme(radius); @include nb-ltr(border-top-right-radius, nb-theme(radius));
@include nb-rtl(border-top-left-radius, nb-theme(radius));
} }
/deep/ nb-sidebar-header { /deep/ nb-sidebar-header {
@ -71,7 +72,8 @@
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
} }
span { span {
padding-left: 0.25rem; @include nb-ltr(padding-left, 0.25rem);
@include nb-rtl(padding-right, 0.25rem);
} }
i, span { i, span {
@ -115,7 +117,8 @@
/deep/ .main-container { /deep/ .main-container {
height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important; height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important;
border-top-right-radius: 0; @include nb-ltr(border-top-right-radius, 0);
@include nb-rtl(border-top-left-radius, 0);
.scrollable { .scrollable {
padding-top: 0; padding-top: 0;

View file

@ -22,7 +22,7 @@ import { Component } from '@angular/core';
<nb-layout-column class="small"> <nb-layout-column class="small">
</nb-layout-column> </nb-layout-column>
<nb-layout-column right> <nb-layout-column>
<ng-content select="router-outlet"></ng-content> <ng-content select="router-outlet"></ng-content>
</nb-layout-column> </nb-layout-column>

View file

@ -50,7 +50,8 @@
/deep/ .main-container { /deep/ .main-container {
height: height:
calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important; calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important;
border-top-right-radius: nb-theme(radius); @include nb-ltr(border-top-right-radius, nb-theme(radius));
@include nb-rtl(border-top-left-radius, nb-theme(radius));
} }
/deep/ nb-sidebar-header { /deep/ nb-sidebar-header {
@ -71,7 +72,8 @@
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
} }
span { span {
padding-left: 0.25rem; @include nb-ltr(padding-left, 0.25rem);
@include nb-rtl(padding-right, 0.25rem);
} }
i, span { i, span {
@ -115,7 +117,8 @@
/deep/ .main-container { /deep/ .main-container {
height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important; height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important;
border-top-right-radius: 0; @include nb-ltr(border-top-right-radius, 0);
@include nb-rtl(border-top-left-radius, 0);
.scrollable { .scrollable {
padding-top: 0; padding-top: 0;

View file

@ -22,7 +22,7 @@ import { Component } from '@angular/core';
<nb-layout-column class="small"> <nb-layout-column class="small">
</nb-layout-column> </nb-layout-column>
<nb-layout-column right> <nb-layout-column>
<ng-content select="router-outlet"></ng-content> <ng-content select="router-outlet"></ng-content>
</nb-layout-column> </nb-layout-column>

193
src/app/@theme/styles/bootstrap-rtl.scss vendored Normal file
View file

@ -0,0 +1,193 @@
@import './themes';
@mixin bootstrap-rtl() {
.btn-group:not(.btn-divided-group) > .btn:not(.dropdown-toggle) {
&:first-child {
@include nb-ltr() {
border-top-left-radius: nb-theme(btn-border-radius);
border-bottom-left-radius: nb-theme(btn-border-radius);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
};
@include nb-rtl() {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: nb-theme(btn-border-radius);
border-bottom-right-radius: nb-theme(btn-border-radius);
};
}
&:last-child {
@include nb-ltr() {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: nb-theme(btn-border-radius);
border-bottom-right-radius: nb-theme(btn-border-radius);
};
@include nb-rtl() {
border-top-left-radius: nb-theme(btn-border-radius);
border-bottom-left-radius: nb-theme(btn-border-radius);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
};
}
}
.btn-group.dropdown {
& > .btn:first-of-type.dropdown-toggle {
@include nb-ltr() {
border-top-left-radius: nb-theme(btn-border-radius);
border-top-right-radius: 0;
};
@include nb-rtl() {
border-top-left-radius: 0;
border-top-right-radius: nb-theme(btn-border-radius);
};
}
& > .btn:last-of-type.dropdown-toggle {
@include nb-ltr() {
border-top-left-radius: 0;
border-top-right-radius: nb-theme(btn-border-radius);
};
@include nb-rtl() {
border-top-left-radius: nb-theme(btn-border-radius);
border-top-right-radius: 0;
};
}
&:not(.show) {
& > .btn:first-of-type.dropdown-toggle {
@include nb-ltr() {
border-bottom-left-radius: nb-theme(btn-border-radius);
border-bottom-right-radius: 0;
};
@include nb-rtl() {
border-bottom-left-radius: 0;
border-bottom-right-radius: nb-theme(btn-border-radius);
};
}
& > .btn:last-of-type.dropdown-toggle {
@include nb-ltr() {
border-bottom-left-radius: 0;
border-bottom-right-radius: nb-theme(btn-border-radius);
};
@include nb-rtl() {
border-bottom-left-radius: nb-theme(btn-border-radius);
border-bottom-right-radius: 0;
};
}
}
}
.btn-group.dropup {
& > .btn:first-of-type.dropdown-toggle {
@include nb-ltr() {
border-bottom-left-radius: nb-theme(btn-border-radius);
border-bottom-right-radius: 0;
};
@include nb-rtl() {
border-bottom-left-radius: 0;
border-bottom-right-radius: nb-theme(btn-border-radius);
};
}
& > .btn:last-of-type.dropdown-toggle {
@include nb-ltr() {
border-bottom-left-radius: 0;
border-bottom-right-radius: nb-theme(btn-border-radius);
};
@include nb-rtl() {
border-bottom-left-radius: nb-theme(btn-border-radius);
border-bottom-right-radius: 0;
};
}
&:not(.show) {
& > .btn:first-of-type.dropdown-toggle {
@include nb-ltr() {
border-top-left-radius: nb-theme(btn-border-radius);
border-top-right-radius: 0;
};
@include nb-rtl() {
border-top-left-radius: 0;
border-top-right-radius: nb-theme(btn-border-radius);
};
}
& > .btn:last-of-type.dropdown-toggle {
@include nb-ltr() {
border-top-left-radius: 0;
border-top-right-radius: nb-theme(btn-border-radius);
};
@include nb-rtl() {
border-top-left-radius: nb-theme(btn-border-radius);
border-top-right-radius: 0;
};
}
}
}
.btn-divided-group {
.btn:not(:first-child) {
@include nb-ltr(margin-left, 0.5rem);
@include nb-rtl(margin-right, 0.5rem);
border-radius: nb-theme(btn-border-radius);
}
}
.input-group-addon,
.input-group-icon {
@include nb-ltr() {
border-left: nb-theme(form-control-border);
border-right: none;
};
@include nb-rtl() {
border-left: none;
border-right: nb-theme(form-control-border);
};
}
.input-group {
.form-control:first-child:not(:only-child),
.input-group-addon:first-child,
.input-group-prepend .btn:first-child,
.input-group-btn .btn:first-child {
@include nb-ltr() {
border-top-left-radius: nb-theme(form-control-border-radius);
border-bottom-left-radius: nb-theme(form-control-border-radius);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
};
@include nb-rtl() {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: nb-theme(form-control-border-radius);
border-bottom-right-radius: nb-theme(form-control-border-radius);
};
}
.form-control:last-child:not(:only-child),
.input-group-addon:last-child,
.input-group-append .btn:last-child,
.input-group-btn .btn:last-child {
@include nb-ltr() {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: nb-theme(form-control-border-radius);
border-bottom-right-radius: nb-theme(form-control-border-radius);
};
@include nb-rtl() {
border-top-left-radius: nb-theme(form-control-border-radius);
border-bottom-left-radius: nb-theme(form-control-border-radius);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
};
}
.dropdown.show .btn.dropdown-toggle {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.dropup.show .btn.dropdown-toggle {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}
}

View file

@ -8,6 +8,8 @@
// loading progress bar theme // loading progress bar theme
@import './pace.theme'; @import './pace.theme';
@import './bootstrap-rtl';
// install the framework and custom global styles // install the framework and custom global styles
@include nb-install() { @include nb-install() {
@ -18,7 +20,9 @@
// loading progress bar // loading progress bar
@include ngx-pace-theme(); @include ngx-pace-theme();
// fixed in rc.9 and can be removed after upgrade
.custom-control .custom-control-indicator { .custom-control .custom-control-indicator {
border-radius: 50%; // TODO: quickfix for https://github.com/akveo/nebular/issues/275 border-radius: 50%; // TODO: quickfix for https://github.com/akveo/nebular/issues/275
} }
@include bootstrap-rtl();
}; };

View file

@ -26,6 +26,8 @@ import {
HeaderComponent, HeaderComponent,
SearchInputComponent, SearchInputComponent,
ThemeSettingsComponent, ThemeSettingsComponent,
SwitcherComponent,
LayoutDirectionSwitcherComponent,
ThemeSwitcherComponent, ThemeSwitcherComponent,
TinyMCEComponent, TinyMCEComponent,
} from './components'; } from './components';
@ -59,6 +61,8 @@ const NB_MODULES = [
]; ];
const COMPONENTS = [ const COMPONENTS = [
SwitcherComponent,
LayoutDirectionSwitcherComponent,
ThemeSwitcherComponent, ThemeSwitcherComponent,
HeaderComponent, HeaderComponent,
FooterComponent, FooterComponent,

View file

@ -8,13 +8,14 @@
padding-bottom: 0.25rem; padding-bottom: 0.25rem;
button { button {
margin: 0 1rem 1rem 0; @include nb-ltr(margin, 0 1rem 1rem 0);
@include nb-rtl(margin, 0 0 1rem 1rem);
} }
} }
/* stylelint-disable */ /* stylelint-disable */
toaster-container /deep/ { toaster-container /deep/ {
#toast-container .toast-close-button { #toast-container .toast-close-button {
right: 0; right: 0;
} }
} }

View file

@ -39,7 +39,8 @@
nb-user /deep/ { nb-user /deep/ {
.info-container { .info-container {
margin-left: 0.875rem; @include nb-ltr(margin-left, 0.875rem);
@include nb-rtl(margin-right, 0.875rem);
} }
.user-name { .user-name {
@ -60,5 +61,3 @@
} }
} }
} }

View file

@ -11,7 +11,7 @@
</div> </div>
<div class="progress-wrap"> <div class="progress-wrap">
<input type="range" class="progress" [value]="getProgress()" min="0" max="100" step="0.01" <input dir="ltr" type="range" class="progress" [value]="getProgress()" min="0" max="100" step="0.01"
(input)="setProgress(duration.value)" #duration> (input)="setProgress(duration.value)" #duration>
<div class="progress-foreground" [style.width.%]="getProgress()"></div> <div class="progress-foreground" [style.width.%]="getProgress()"></div>
</div> </div>

View file

@ -60,6 +60,7 @@
background-color: nb-theme(color-success); background-color: nb-theme(color-success);
height: 2px; height: 2px;
position: absolute; position: absolute;
left: 0;
margin-top: calc(0.75rem - 1px); margin-top: calc(0.75rem - 1px);
width: 100px; width: 100px;
@ -107,12 +108,22 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
color: nb-theme(color-fg); color: nb-theme(color-fg);
.current {
@include nb-ltr(order, 0);
@include nb-rtl(order, 1);
}
.remaining {
@include nb-ltr(order, 1);
@include nb-rtl(order, 0);
}
} }
.controls { .controls {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@include nb-rtl(flex-direction, row-reverse);
padding: 0.25rem 2rem 1rem; padding: 0.25rem 2rem 1rem;
max-width: 400px; max-width: 400px;
width: 100%; width: 100%;
@ -171,6 +182,7 @@
width: 80%; width: 80%;
.progress-foreground { .progress-foreground {
left: auto;
margin-top: calc(1rem + 1px); margin-top: calc(1rem + 1px);
z-index: 0; z-index: 0;
} }

View file

@ -40,11 +40,13 @@
} }
a:first-child { a:first-child {
border-left: 1px solid nb-theme(separator); @include nb-ltr(border-left, 1px solid nb-theme(separator));
@include nb-rtl(border-right, 1px solid nb-theme(separator));
} }
a:last-child { a:last-child {
border-top-right-radius: nb-theme(card-border-radius); @include nb-ltr(border-top-right-radius, nb-theme(card-border-radius));
@include nb-rtl(border-top-left-radius, nb-theme(card-border-radius));
} }
a.active { a.active {

View file

@ -13,6 +13,7 @@
.echart { .echart {
position: absolute; position: absolute;
left: 1em;
height: calc(100% - 2 * #{$padding}); height: calc(100% - 2 * #{$padding});
width: 40%; width: 40%;
} }

View file

@ -90,7 +90,8 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
height: 100%; height: 100%;
padding: 0 0.5rem 0 0.75rem; @include nb-ltr(padding, 0 0.5rem 0 0.75rem);
@include nb-rtl(padding, 0 0.75rem 0 0.5rem);
border-left: 1px solid transparent; border-left: 1px solid transparent;
} }
@ -112,7 +113,8 @@
@include nb-for-theme(cosmic) { @include nb-for-theme(cosmic) {
nb-card { nb-card {
&.off .icon-container { &.off .icon-container {
border-right: 1px solid nb-theme(separator); @include nb-ltr(border-right, 1px solid nb-theme(separator));
@include nb-rtl(border-left, 1px solid nb-theme(separator));
} }
.icon-container { .icon-container {
@ -120,14 +122,16 @@
} }
.details { .details {
padding-left: 1.25rem; @include nb-ltr(padding-left, 1.25rem);
@include nb-rtl(padding-right, 1.25rem);
} }
.icon { .icon {
width: 7rem; width: 7rem;
height: 100%; height: 100%;
font-size: 4.5rem; font-size: 4.5rem;
border-radius: nb-theme(card-border-radius) 0 0 nb-theme(card-border-radius); @include nb-ltr(border-radius, nb-theme(card-border-radius) 0 0 nb-theme(card-border-radius));
@include nb-rtl(border-radius, 0 nb-theme(card-border-radius) nb-theme(card-border-radius) 0);
} }
.title { .title {

View file

@ -73,7 +73,7 @@
</span> </span>
</div> </div>
<div class="input-group"> <div class="input-group">
<div class="dropdown input-group-btn" ngbDropdown> <div class="dropdown input-group-prepend input-group-btn" ngbDropdown>
<button type="button" class="btn btn-success dropdown-toggle" ngbDropdownToggle> <button type="button" class="btn btn-success dropdown-toggle" ngbDropdownToggle>
Action Action
</button> </button>

View file

@ -70,7 +70,8 @@
.current-rate { .current-rate {
font-size: 1.5rem; font-size: 1.5rem;
padding-left: 1rem; @include nb-ltr(padding-left, 1rem);
@include nb-rtl(padding-right, 1rem);
color: nb-theme(color-fg-heading); color: nb-theme(color-fg-heading);
} }
@ -82,6 +83,7 @@
position: relative; position: relative;
.form-control { .form-control {
padding-left: 3rem; padding-left: 3rem;
} }

View file

@ -1,16 +1,21 @@
.full-width { @import '../../../@theme/styles/themes';
flex: 1;
min-width: 220px;
}
nb-checkbox { @include nb-install-component() {
margin-bottom: 1rem; .full-width {
} flex: 1;
min-width: 220px;
}
.form-inline > * { nb-checkbox {
margin: 0 1.5rem 1.5rem 0; margin-bottom: 1rem;
} }
nb-card.inline-form-card nb-card-body { .form-inline > * {
padding-bottom: 0; @include nb-ltr(margin, 0 1.5rem 1.5rem 0);
@include nb-rtl(margin, 0 0 1.5rem 1.5rem);
}
nb-card.inline-form-card nb-card-body {
padding-bottom: 0;
}
} }

View file

@ -30,7 +30,8 @@
padding: 0.75rem; padding: 0.75rem;
.action-groups-header { .action-groups-header {
margin: 0 0 0.5rem 0.25rem; @include nb-ltr(margin, 0 0 0.5rem 0.25rem);
@include nb-rtl(margin, 0 0.25rem 0.5rem 0);
} }
} }

View file

@ -10,7 +10,8 @@
} }
.pagination-container { .pagination-container {
margin-right: 1rem; @include nb-ltr(margin-right, 1rem);
@include nb-rtl(margin-left, 1rem);
.btn-group > .btn { .btn-group > .btn {
padding-left: 1.125rem; padding-left: 1.125rem;
@ -53,7 +54,8 @@
> label { > label {
flex-basis: 10%; flex-basis: 10%;
margin: 0 0.25rem 0.5rem 0; @include nb-ltr(margin, 0 0.25rem 0.5rem 0);
@include nb-rtl(margin, 0 0 0.5rem 0.25rem);
} }
} }

View file

@ -46,12 +46,14 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
margin-left: 1rem; margin-left: 1rem;
margin-right: 1rem;
height: $button-size; height: $button-size;
} }
} }
.example-container { .example-container {
padding-right: 0; @include nb-ltr(padding-right, 0);
@include nb-rtl(padding-left, 0);
} }
.example-container .container-btn { .example-container .container-btn {
@ -78,7 +80,8 @@
/deep/.icon-buttons .icon-button-examples { /deep/.icon-buttons .icon-button-examples {
button { button {
margin-right: 1rem; @include nb-ltr(margin-right, 1rem);
@include nb-rtl(margin-left, 1rem);
} }
} }

View file

@ -18,10 +18,9 @@ nb-card-body {
.icon-button-examples { .icon-button-examples {
display: flex; display: flex;
justify-content: flex-start; justify-content: space-between;
button { button {
margin-right: 2rem;
min-width: 4rem; min-width: 4rem;
} }
} }

View file

@ -12,7 +12,8 @@
i { i {
color: nb-theme(color-fg); color: nb-theme(color-fg);
font-size: 2.5rem; font-size: 2.5rem;
margin-right: 1rem; @include nb-ltr(margin-right, 1rem);
@include nb-rtl(margin-left, 1rem);
} }
span { span {
@ -37,7 +38,8 @@
font-size: 0.75rem; font-size: 0.75rem;
i { i {
font-size: 2rem; font-size: 2rem;
margin-right: 0.5rem; @include nb-ltr(margin-right, 0.5rem);
@include nb-rtl(margin-left, 0.5rem);
} }
} }
} }

View file

@ -1,4 +1,8 @@
@import '~@nebular/theme/styles/core/mixins';
button { :host {
margin: 0 0.75rem 2rem 0; button {
@include nb-ltr(margin, 0 0.75rem 2rem 0);
@include nb-rtl(margin, 0 0 2rem 0.75rem);
}
} }

View file

@ -1,6 +1,4 @@
button.with-margins { @import '~@nebular/theme/styles/core/mixins';
margin: 0 0.75rem 2rem 0;
}
/deep/ nb-card.popover-card { /deep/ nb-card.popover-card {
margin-bottom: 0; margin-bottom: 0;
@ -8,6 +6,14 @@ button.with-margins {
box-shadow: none; box-shadow: none;
} }
:host /deep/ .btn-outline-secondary { :host {
margin: 0 0.5rem 0.5rem 0; button.with-margins {
@include nb-ltr(margin, 0 0.75rem 2rem 0);
@include nb-rtl(margin, 0 0 2rem 0.75rem);
}
/deep/ .btn-outline-secondary {
@include nb-ltr(margin, 0 0.5rem 0.5rem 0);
@include nb-rtl(margin, 0 0 0.5rem 0.5rem);
}
} }

View file

@ -76,6 +76,7 @@
align-items: flex-end; align-items: flex-end;
span { span {
padding-right: 1rem;
padding-left: 1rem; padding-left: 1rem;
font-size: 1.5rem; font-size: 1.5rem;
} }
@ -108,7 +109,8 @@
height: 60px; height: 60px;
border-top-right-radius: 1rem; border-top-right-radius: 1rem;
border-bottom-left-radius: 1rem; border-bottom-left-radius: 1rem;
margin-right: 1rem; @include nb-ltr(margin-right, 1rem);
@include nb-rtl(margin-left, 1rem);
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {