From f0a461a24d1f4e9a90bf246500fea0f6f72e9a8e Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 30 Mar 2018 10:02:23 +0300 Subject: [PATCH 01/89] feat(rtl): add rtl properties mixins --- src/framework/theme/styles/core/_mixins.scss | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/framework/theme/styles/core/_mixins.scss b/src/framework/theme/styles/core/_mixins.scss index ef5b06a39b..d1ead506fc 100644 --- a/src/framework/theme/styles/core/_mixins.scss +++ b/src/framework/theme/styles/core/_mixins.scss @@ -193,3 +193,18 @@ } } } + +@mixin rtl($prop, $ltr-value, $rtl-value) { + #{$prop}: $ltr-value; + [dir=rtl] & { + #{$prop}: $rtl-value; + } +} + +@mixin rtl-prop($ltr-prop, $rtl-prop, $value, $reset-value) { + #{$ltr-prop}: $value; + [dir=rtl] & { + #{$ltr-prop}: $reset-value; + #{$rtl-prop}: $value; + } +} From 08dcdfa64ba1a23cc21adb50eb7438558ee68634 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 30 Mar 2018 10:07:40 +0300 Subject: [PATCH 02/89] feat(rlt): support in actions component --- .../actions/_actions.component.theme.scss | 25 +++++++++++++++++-- .../components/actions/actions.component.scss | 4 --- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/framework/theme/components/actions/_actions.component.theme.scss b/src/framework/theme/components/actions/_actions.component.theme.scss index 78bc689f5f..e076e2169e 100644 --- a/src/framework/theme/components/actions/_actions.component.theme.scss +++ b/src/framework/theme/components/actions/_actions.component.theme.scss @@ -15,6 +15,15 @@ height: nb-theme(actions-size-small); padding: 0 nb-theme(actions-padding); + &:first-child { + @include rtl-prop( + border-left, + border-right, + none!important, + 1px solid nb-theme(actions-separator) + ); + } + a.icon-container { &:hover, &:focus { text-decoration: none; @@ -25,7 +34,13 @@ color: nb-theme(actions-fg); font-size: nb-theme(actions-size-small); } - border-left: 1px solid nb-theme(actions-separator); + + @include rtl-prop( + border-left, + border-right, + 1px solid nb-theme(actions-separator), + none + ); background: transparent; } @@ -34,7 +49,13 @@ i.control-icon { color: nb-theme(actions-bg); } - border-left: 1px solid nb-theme(actions-separator); + + @include rtl-prop( + border-left, + border-right, + 1px solid nb-theme(actions-separator), + none + ); } } diff --git a/src/framework/theme/components/actions/actions.component.scss b/src/framework/theme/components/actions/actions.component.scss index df60c1a09a..34afbf7e0e 100644 --- a/src/framework/theme/components/actions/actions.component.scss +++ b/src/framework/theme/components/actions/actions.component.scss @@ -15,10 +15,6 @@ align-items: center; position: relative; - &:first-child { - border-left: none!important; - } - i.control-icon { &:hover { cursor: pointer; From 9e083dbc08d4ca7b67931edf4774b6de81bbcc3d Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 30 Mar 2018 11:00:35 +0300 Subject: [PATCH 03/89] feat(rtl): support on flip card --- .../components/card/flip-card/_flip-card.component.theme.scss | 4 ++++ .../theme/components/card/flip-card/flip-card.component.scss | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss b/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss index 6b4503b225..52b5a2d2bc 100644 --- a/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss +++ b/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss @@ -4,4 +4,8 @@ margin-bottom: nb-theme(card-margin); padding: nb-theme(card-padding); } + + .flipcard-body .front-container { + @include rtl-prop(margin-right, margin-left, -100%, unset); + } } diff --git a/src/framework/theme/components/card/flip-card/flip-card.component.scss b/src/framework/theme/components/card/flip-card/flip-card.component.scss index 081856f655..4684142d5b 100644 --- a/src/framework/theme/components/card/flip-card/flip-card.component.scss +++ b/src/framework/theme/components/card/flip-card/flip-card.component.scss @@ -39,10 +39,6 @@ } } - .front-container { - margin-right: -100%; - } - .back-container { transform: rotateY(180deg); } From 1f151ea4a7cc7d8d0d96930df75a42236d867824 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 13:15:00 +0300 Subject: [PATCH 04/89] feat(rtl): add direction service --- src/framework/theme/index.ts | 1 + .../theme/services/direction.service.ts | 25 +++++++++++++++++++ src/framework/theme/theme.module.ts | 10 +++++++- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/framework/theme/services/direction.service.ts diff --git a/src/framework/theme/index.ts b/src/framework/theme/index.ts index 79bbd22cc6..ac21e22586 100644 --- a/src/framework/theme/index.ts +++ b/src/framework/theme/index.ts @@ -10,6 +10,7 @@ export * from './services/theme.service'; export * from './services/spinner.service'; export * from './services/breakpoints.service'; export * from './services/color.helper'; +export * from './services/direction.service'; export * from './components/card/card.module'; export * from './components/layout/layout.module'; export * from './components/menu/menu.module'; diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts new file mode 100644 index 0000000000..18c266d82f --- /dev/null +++ b/src/framework/theme/services/direction.service.ts @@ -0,0 +1,25 @@ +import { InjectionToken, Optional, Inject, Injectable } from '@angular/core'; +import { NbDocument } from '../theme.options'; + +export type Direction = 'ltr' | 'rtl'; + +export const LAYOUT_DIRECTION = new InjectionToken('Flow direction'); + +@Injectable() +export class NbDirectionService { + constructor( + private document: NbDocument, + @Optional() @Inject(LAYOUT_DIRECTION) private dir: Direction = 'ltr', + ) { + this.setDirection(dir); + } + + getDirection(): Direction { + return this.dir; + } + + setDirection(dir: Direction) { + this.dir = dir; + this.document.dir = this.dir; + } +} diff --git a/src/framework/theme/theme.module.ts b/src/framework/theme/theme.module.ts index a5238c7890..f2b1727a0f 100644 --- a/src/framework/theme/theme.module.ts +++ b/src/framework/theme/theme.module.ts @@ -25,6 +25,7 @@ import { NbMediaBreakpoint, NbMediaBreakpointsService, } from './services/breakpoints.service'; +import { NbDirectionService, Direction, LAYOUT_DIRECTION } from './services/direction.service'; export function nbWindowFactory() { return window; @@ -51,7 +52,8 @@ export class NbThemeModule { */ static forRoot(nbThemeOptions: NbThemeOptions, nbJSThemes?: NbJSThemeOptions[], - nbMediaBreakpoints?: NbMediaBreakpoint[]): ModuleWithProviders { + nbMediaBreakpoints?: NbMediaBreakpoint[], + layoutDirection?: Direction): ModuleWithProviders { return { ngModule: NbThemeModule, @@ -66,6 +68,12 @@ export class NbThemeModule { NbThemeService, NbMediaBreakpointsService, NbSpinnerService, + { provide: LAYOUT_DIRECTION, useValue: layoutDirection || 'ltr' }, + { + provide: NbDirectionService, + useClass: NbDirectionService, + deps: [ NbDocument, LAYOUT_DIRECTION ], + }, ], }; } From aa0a26e7fa90101f8968c480ef69d1fb3063c6c5 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 13:21:10 +0300 Subject: [PATCH 05/89] style(checkbox-component): fix typo --- .../components/checkbox/_checkbox.component.theme.scss | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss index f67ce5f85a..da18c34963 100644 --- a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss +++ b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss @@ -14,7 +14,7 @@ } } // locally used mixin -@mixin chackbox-checkmark($size, $color, $border-size) { +@mixin checkbox-checkmark($size, $color, $border-size) { &::before { content: ''; position: absolute; @@ -65,7 +65,7 @@ display: flex; justify-content: center; - @include chackbox-checkmark( + @include checkbox-checkmark( nb-theme(checkbox-size), nb-theme(checkbox-checkmark), nb-theme(checkbox-border-size) @@ -90,7 +90,7 @@ display: flex; justify-content: center; - @include chackbox-checkmark( + @include checkbox-checkmark( nb-theme(checkbox-checked-size), nb-theme(checkbox-checked-checkmark), nb-theme(checkbox-checked-border-size) @@ -109,7 +109,7 @@ display: flex; justify-content: center; - @include chackbox-checkmark( + @include checkbox-checkmark( nb-theme(checkbox-disabled-size), nb-theme(checkbox-checkmark), nb-theme(checkbox-disabled-border-size) @@ -134,7 +134,7 @@ display: flex; justify-content: center; - @include chackbox-checkmark( + @include checkbox-checkmark( nb-theme(checkbox-disabled-size), nb-theme(checkbox-disabled-checkmark), nb-theme(checkbox-disabled-border-size) From 18d955f0389d12253ef0acd1c4e70c8064606738 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 13:44:46 +0300 Subject: [PATCH 06/89] feat(rtl): checkbox support --- .../theme/components/checkbox/_checkbox.component.theme.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss index da18c34963..b10c0fb03a 100644 --- a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss +++ b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss @@ -35,7 +35,7 @@ // locally used mixin @mixin description-style { color: nb-theme(color-fg-heading); - padding-left: 0.25rem; + @include rtl-prop(padding-left, padding-right, 0.25rem, 0); } @mixin nb-checkbox-theme() { @@ -60,7 +60,7 @@ position: absolute; top: 50%; transform: translateY(-50%); - left: 0; + @include rtl-prop(left, right, 0, unset); flex: none; display: flex; justify-content: center; From f26549b93df9afb68364621b9283b05632e06241 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 14:28:47 +0300 Subject: [PATCH 07/89] feat(rtl): add rtl only mixin --- src/framework/theme/styles/core/_mixins.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/framework/theme/styles/core/_mixins.scss b/src/framework/theme/styles/core/_mixins.scss index d1ead506fc..99ae3a3cd9 100644 --- a/src/framework/theme/styles/core/_mixins.scss +++ b/src/framework/theme/styles/core/_mixins.scss @@ -208,3 +208,9 @@ #{$rtl-prop}: $value; } } + +@mixin rtl-only($prop, $value) { + [dir=rtl] & { + #{$prop}: $value; + } +} From bc1702f752c30d091945ac4f1e32580a62344601 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 15:17:53 +0300 Subject: [PATCH 08/89] feat(rlt): add support in context-menu --- .../components/context-menu/context-menu.component.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/framework/theme/components/context-menu/context-menu.component.scss b/src/framework/theme/components/context-menu/context-menu.component.scss index 72f9388557..1f093bc43e 100644 --- a/src/framework/theme/components/context-menu/context-menu.component.scss +++ b/src/framework/theme/components/context-menu/context-menu.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.scss'; + :host /deep/ nb-menu { display: inline; font-size: 0.875rem; @@ -33,10 +35,11 @@ .menu-title { padding: 0.375rem 3rem; + @include rtl-only(text-align, right); } .menu-icon ~ .menu-title { - padding-left: 0; + @include rtl-prop(padding-left, padding-right, 0, 3rem); } .menu-icon:first-child { From e515c325827a08016a9bcbc77bcfea22ab44ba0f Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 15:32:35 +0300 Subject: [PATCH 09/89] style(contenxt-menu): change import --- .../theme/components/context-menu/context-menu.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/theme/components/context-menu/context-menu.component.scss b/src/framework/theme/components/context-menu/context-menu.component.scss index 1f093bc43e..fae02c85a3 100644 --- a/src/framework/theme/components/context-menu/context-menu.component.scss +++ b/src/framework/theme/components/context-menu/context-menu.component.scss @@ -4,7 +4,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -@import '../../styles/core/_mixins.scss'; +@import '../../styles/core/mixins'; :host /deep/ nb-menu { display: inline; From dfba68d647bd77f90bf54c253d41f30b8530316d Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 15:50:01 +0300 Subject: [PATCH 10/89] feat(rtl): badge support --- e2e/actions.e2e-spec.ts | 14 +++++++------- e2e/tabset.e2e-spec.ts | 10 +++++----- e2e/user.e2e-spec.ts | 10 +++++----- src/app/actions-test/actions-test.component.ts | 12 ++++++------ src/app/tabset-test/tabset-test.component.ts | 16 ++++++++-------- src/app/user-test/user-test.component.ts | 8 ++++---- .../components/actions/actions.component.ts | 2 +- .../theme/components/badge/badge.component.scss | 15 +++++++++++---- .../theme/components/badge/badge.component.ts | 16 ++++++++-------- .../theme/components/tabset/tabset.component.ts | 2 +- .../theme/components/user/user.component.ts | 2 +- 11 files changed, 57 insertions(+), 50 deletions(-) diff --git a/e2e/actions.e2e-spec.ts b/e2e/actions.e2e-spec.ts index b122558093..0c3c33f852 100644 --- a/e2e/actions.e2e-spec.ts +++ b/e2e/actions.e2e-spec.ts @@ -19,13 +19,13 @@ describe('nb-action', () => { const badgesConf = { selector: (i) => `nb-card:nth-child(4) nb-actions nb-action:nth-child(${i + 1}) nb-badge > span`, badges: [ - { position: NbBadgeComponent.BOTTOM_LEFT, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, - { position: NbBadgeComponent.TOP_LEFT, status: NbBadgeComponent.STATUS_DANGER, text: badgeText }, - { position: NbBadgeComponent.BOTTOM_RIGHT, status: NbBadgeComponent.STATUS_WARNING, text: badgeText }, - { position: NbBadgeComponent.BOTTOM_LEFT, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, - { position: NbBadgeComponent.TOP_RIGHT, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, - { position: NbBadgeComponent.TOP_RIGHT, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, - { position: NbBadgeComponent.TOP_RIGHT, status: NbBadgeComponent.STATUS_PRIMARY, text: badgeText }, + { position: NbBadgeComponent.BOTTOM_START, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, + { position: NbBadgeComponent.TOP_START, status: NbBadgeComponent.STATUS_DANGER, text: badgeText }, + { position: NbBadgeComponent.BOTTOM_END, status: NbBadgeComponent.STATUS_WARNING, text: badgeText }, + { position: NbBadgeComponent.BOTTOM_START, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, + { position: NbBadgeComponent.TOP_END, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, + { position: NbBadgeComponent.TOP_END, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, + { position: NbBadgeComponent.TOP_END, status: NbBadgeComponent.STATUS_PRIMARY, text: badgeText }, ], }; badgeTests(badgesConf); diff --git a/e2e/tabset.e2e-spec.ts b/e2e/tabset.e2e-spec.ts index 2b48e1209c..3c8f66afdc 100644 --- a/e2e/tabset.e2e-spec.ts +++ b/e2e/tabset.e2e-spec.ts @@ -103,11 +103,11 @@ describe('nb-tabset', () => { const badgesConf = { selector: (i) => `nb-tabset:nth-child(6) > ul > li:nth-child(${i + 1}) > nb-badge > span`, badges: [ - { text: badgeText, status: NbBadgeComponent.STATUS_PRIMARY, position: NbBadgeComponent.TOP_RIGHT }, - { text: badgeText, status: NbBadgeComponent.STATUS_INFO, position: NbBadgeComponent.TOP_LEFT }, - { text: badgeText, status: NbBadgeComponent.STATUS_SUCCESS, position: NbBadgeComponent.BOTTOM_RIGHT }, - { text: badgeText, status: NbBadgeComponent.STATUS_DANGER, position: NbBadgeComponent.BOTTOM_LEFT }, - { text: badgeText, status: NbBadgeComponent.STATUS_WARNING, position: NbBadgeComponent.BOTTOM_RIGHT }, + { text: badgeText, status: NbBadgeComponent.STATUS_PRIMARY, position: NbBadgeComponent.TOP_END }, + { text: badgeText, status: NbBadgeComponent.STATUS_INFO, position: NbBadgeComponent.TOP_START }, + { text: badgeText, status: NbBadgeComponent.STATUS_SUCCESS, position: NbBadgeComponent.BOTTOM_END }, + { text: badgeText, status: NbBadgeComponent.STATUS_DANGER, position: NbBadgeComponent.BOTTOM_START }, + { text: badgeText, status: NbBadgeComponent.STATUS_WARNING, position: NbBadgeComponent.BOTTOM_END }, ], }; badgeTests(badgesConf); diff --git a/e2e/user.e2e-spec.ts b/e2e/user.e2e-spec.ts index 309d28ed59..d4ad7f8792 100644 --- a/e2e/user.e2e-spec.ts +++ b/e2e/user.e2e-spec.ts @@ -26,11 +26,11 @@ describe('nb-user', () => { const badgesConf = { selector: (i) => `.test-row:nth-child(${elementsOffset + i + 1}) nb-badge > span`, badges: [ - { position: NbBadgeComponent.TOP_RIGHT, status: NbBadgeComponent.STATUS_PRIMARY, text: badgeText }, - { position: NbBadgeComponent.TOP_LEFT, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, - { position: NbBadgeComponent.BOTTOM_RIGHT, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, - { position: NbBadgeComponent.BOTTOM_LEFT, status: NbBadgeComponent.STATUS_WARNING, text: badgeText }, - { position: NbBadgeComponent.TOP_LEFT, status: NbBadgeComponent.STATUS_DANGER, text: badgeText }, + { position: NbBadgeComponent.TOP_END, status: NbBadgeComponent.STATUS_PRIMARY, text: badgeText }, + { position: NbBadgeComponent.TOP_START, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, + { position: NbBadgeComponent.BOTTOM_END, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, + { position: NbBadgeComponent.BOTTOM_START, status: NbBadgeComponent.STATUS_WARNING, text: badgeText }, + { position: NbBadgeComponent.TOP_START, status: NbBadgeComponent.STATUS_DANGER, text: badgeText }, ], }; badgeTests(badgesConf); diff --git a/src/app/actions-test/actions-test.component.ts b/src/app/actions-test/actions-test.component.ts index 03d73ed097..9cdf6989f2 100644 --- a/src/app/actions-test/actions-test.component.ts +++ b/src/app/actions-test/actions-test.component.ts @@ -88,37 +88,37 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone + [badgePosition]="badge.BOTTOM_START"> diff --git a/src/app/tabset-test/tabset-test.component.ts b/src/app/tabset-test/tabset-test.component.ts index 6ad5e624a1..d88828c301 100644 --- a/src/app/tabset-test/tabset-test.component.ts +++ b/src/app/tabset-test/tabset-test.component.ts @@ -82,25 +82,25 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone + [badgePosition]="badge.TOP_START"> Content #2 + [badgePosition]="badge.BOTTOM_END"> Content #3 + [badgePosition]="badge.BOTTOM_START"> Content #4 + [badgePosition]="badge.BOTTOM_END"> Content #5 @@ -111,25 +111,25 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone + [badgePosition]="badge.BOTTOM_END"> Content #2 + [badgePosition]="badge.TOP_START"> Content #3 + [badgePosition]="badge.BOTTOM_START"> Content #4 + [badgePosition]="badge.BOTTOM_END"> Content #5 diff --git a/src/app/user-test/user-test.component.ts b/src/app/user-test/user-test.component.ts index b29071f220..7d5bb416da 100644 --- a/src/app/user-test/user-test.component.ts +++ b/src/app/user-test/user-test.component.ts @@ -65,7 +65,7 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone title="Worker" badgeText="29" [badgeStatus]="badge.STATUS_INFO" - [badgePosition]="badge.TOP_LEFT"> + [badgePosition]="badge.TOP_START">
@@ -76,7 +76,7 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone showTitle="false" badgeText="29" [badgeStatus]="badge.STATUS_SUCCESS" - [badgePosition]="badge.BOTTOM_RIGHT"> + [badgePosition]="badge.BOTTOM_END">
@@ -87,7 +87,7 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone title="Worker" badgeText="29" [badgeStatus]="badge.STATUS_WARNING" - [badgePosition]="badge.BOTTOM_LEFT"> + [badgePosition]="badge.BOTTOM_START">
@@ -98,7 +98,7 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone title="Worker" badgeText="29" [badgeStatus]="badge.STATUS_DANGER" - [badgePosition]="badge.TOP_LEFT"> + [badgePosition]="badge.TOP_START">
diff --git a/src/framework/theme/components/actions/actions.component.ts b/src/framework/theme/components/actions/actions.component.ts index b43e686e94..d30823fc0b 100644 --- a/src/framework/theme/components/actions/actions.component.ts +++ b/src/framework/theme/components/actions/actions.component.ts @@ -62,7 +62,7 @@ export class NbActionComponent { /** * Badge position. * Can be set to any class or to one of predefined positions: - * 'top left', 'top right', 'bottom left', 'bottom right' + * 'top start', 'top end', 'bottom start', 'bottom end' * @type string */ @Input() badgePosition: string; diff --git a/src/framework/theme/components/badge/badge.component.scss b/src/framework/theme/components/badge/badge.component.scss index 95d53bd97a..75e2aa4e9a 100644 --- a/src/framework/theme/components/badge/badge.component.scss +++ b/src/framework/theme/components/badge/badge.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'; + .nb-badge { position: absolute; padding: 0.25em 0.4em; @@ -15,8 +17,13 @@ vertical-align: baseline; border-radius: 0.25rem; - &.top { top: 0; } - &.right { right: 0; } - &.bottom { bottom: 0; } - &.left { left: 0; } + &.top { top: 0; } + &.bottom { bottom: 0; } + + &.start { + @include rtl-prop(left, right, 0, none); + } + &.end { + @include rtl-prop(right, left, 0, none); + } } diff --git a/src/framework/theme/components/badge/badge.component.ts b/src/framework/theme/components/badge/badge.component.ts index edf98d968c..0375bf72b2 100644 --- a/src/framework/theme/components/badge/badge.component.ts +++ b/src/framework/theme/components/badge/badge.component.ts @@ -22,10 +22,10 @@ import { Component, Input } from '@angular/core'; * * ``` * - * @example Badge located on the bottom right with warning status: + * @example Badge located on the bottom end with warning status: * * ``` - * + * * * ``` * @@ -46,10 +46,10 @@ import { Component, Input } from '@angular/core'; `, }) export class NbBadgeComponent { - static readonly TOP_LEFT = 'top left'; - static readonly TOP_RIGHT = 'top right'; - static readonly BOTTOM_LEFT = 'bottom left'; - static readonly BOTTOM_RIGHT = 'bottom right'; + static readonly TOP_START = 'top start'; + static readonly TOP_END = 'top end'; + static readonly BOTTOM_START = 'bottom start'; + static readonly BOTTOM_END = 'bottom end'; static readonly STATUS_PRIMARY = 'primary'; static readonly STATUS_INFO = 'info'; @@ -57,7 +57,7 @@ export class NbBadgeComponent { static readonly STATUS_WARNING = 'warning'; static readonly STATUS_DANGER = 'danger'; - positionClass: string = NbBadgeComponent.TOP_RIGHT; + positionClass: string = NbBadgeComponent.TOP_END; colorClass: string = NbBadgeComponent.STATUS_PRIMARY; /** @@ -70,7 +70,7 @@ export class NbBadgeComponent { * Badge position * * Can be set to any class or to one of predefined positions: - * 'top left', 'top right', 'bottom left', 'bottom right' + * 'top start', 'top end', 'bottom start', 'bottom end' * @type string */ @Input() set position(value) { diff --git a/src/framework/theme/components/tabset/tabset.component.ts b/src/framework/theme/components/tabset/tabset.component.ts index ceb8a85a5f..27ee18361f 100644 --- a/src/framework/theme/components/tabset/tabset.component.ts +++ b/src/framework/theme/components/tabset/tabset.component.ts @@ -78,7 +78,7 @@ export class NbTabComponent { /** * Badge position. * Can be set to any class or to one of predefined positions: - * 'top left', 'top right', 'bottom left', 'bottom right' + * 'top start', 'top end', 'bottom start', 'bottom end' * @type string */ @Input() badgePosition: string; diff --git a/src/framework/theme/components/user/user.component.ts b/src/framework/theme/components/user/user.component.ts index 54dae404ff..dd4eef2ae7 100644 --- a/src/framework/theme/components/user/user.component.ts +++ b/src/framework/theme/components/user/user.component.ts @@ -167,7 +167,7 @@ export class NbUserComponent { /** * Badge position. * Can be set to any class or to one of predefined positions: - * 'top left', 'top right', 'bottom left', 'bottom right' + * 'top start', 'top end', 'bottom start', 'bottom end' * @type string */ @Input() badgePosition: string; From 11f00f9f338f2e09255db34455048c762afaf1fe Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 18:32:08 +0300 Subject: [PATCH 11/89] fix(direction-service): remove type from constructor parameter It's not possible to use @Inject with type. See https://github.com/angular/angular/issues/15640 --- src/framework/theme/services/direction.service.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index 18c266d82f..4a8d701fd8 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -7,11 +7,14 @@ export const LAYOUT_DIRECTION = new InjectionToken('Flow direction'); @Injectable() export class NbDirectionService { + dir: Direction; + constructor( private document: NbDocument, - @Optional() @Inject(LAYOUT_DIRECTION) private dir: Direction = 'ltr', + @Optional() @Inject(LAYOUT_DIRECTION) dir = 'ltr', ) { - this.setDirection(dir); + this.dir = dir; + this.setDirection(dir); } getDirection(): Direction { From 4a8df51bd51abbf83a47be3ab3c839501ee3944e Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 20:59:42 +0300 Subject: [PATCH 12/89] feat(rtl): add styles for search close button --- .../search/styles/search.component.column-curtain.scss | 4 +++- .../components/search/styles/search.component.curtain.scss | 4 +++- .../search/styles/search.component.layout-rotate.scss | 4 +++- .../components/search/styles/search.component.modal-drop.scss | 4 +++- .../components/search/styles/search.component.modal-half.scss | 4 +++- .../components/search/styles/search.component.modal-move.scss | 4 +++- .../search/styles/search.component.modal-zoomin.scss | 4 +++- 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/framework/theme/components/search/styles/search.component.column-curtain.scss b/src/framework/theme/components/search/styles/search.component.column-curtain.scss index 82f544a9a4..ae011d1aa0 100644 --- a/src/framework/theme/components/search/styles/search.component.column-curtain.scss +++ b/src/framework/theme/components/search/styles/search.component.column-curtain.scss @@ -4,6 +4,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ +@import '../../../styles/core/mixins'; + /deep/ nb-layout.column-curtain.with-search .layout { pointer-events: none; } @@ -41,7 +43,7 @@ button { position: absolute; top: 2rem; - right: 2rem; + @include rtl-prop(right, left, 2rem, auto); font-size: 2.5rem; opacity: 0; transition: opacity 0.5s; diff --git a/src/framework/theme/components/search/styles/search.component.curtain.scss b/src/framework/theme/components/search/styles/search.component.curtain.scss index efb2e62a47..e9e728fbf1 100644 --- a/src/framework/theme/components/search/styles/search.component.curtain.scss +++ b/src/framework/theme/components/search/styles/search.component.curtain.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.curtain { .search { @@ -35,7 +37,7 @@ font-size: 2.5rem; position: absolute; top: 3rem; - right: 3rem; + @include rtl-prop(right, left, 3rem, auto); transition: opacity 0.1s; transition-delay: 0.3s; } diff --git a/src/framework/theme/components/search/styles/search.component.layout-rotate.scss b/src/framework/theme/components/search/styles/search.component.layout-rotate.scss index d10f7c0f7c..03617b7b7f 100644 --- a/src/framework/theme/components/search/styles/search.component.layout-rotate.scss +++ b/src/framework/theme/components/search/styles/search.component.layout-rotate.scss @@ -4,6 +4,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ +@import '../../../styles/core/mixins'; + /deep/ nb-layout.rotate-layout { position: fixed; overflow: hidden; @@ -48,7 +50,7 @@ button { position: absolute; top: 3rem; - right: 3rem; + @include rtl-prop(right, left, 3rem, auto); font-size: 2.5rem; opacity: 0; transform: scale3d(0.8, 0.8, 1); diff --git a/src/framework/theme/components/search/styles/search.component.modal-drop.scss b/src/framework/theme/components/search/styles/search.component.modal-drop.scss index f8f50efaa7..6b84ae2a18 100644 --- a/src/framework/theme/components/search/styles/search.component.modal-drop.scss +++ b/src/framework/theme/components/search/styles/search.component.modal-drop.scss @@ -4,6 +4,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ +@import '../../../styles/core/mixins'; + /deep/ nb-layout.modal-drop .layout { position: relative; transition: transform 0.4s, opacity 0.4s; @@ -48,7 +50,7 @@ font-size: 2.5rem; position: absolute; top: 3rem; - right: 3rem; + @include rtl-prop(right, left, 3rem, auto); display: block; opacity: 0; transition: opacity 0.4s; diff --git a/src/framework/theme/components/search/styles/search.component.modal-half.scss b/src/framework/theme/components/search/styles/search.component.modal-half.scss index 6f52fa29f0..1c2c9cc749 100644 --- a/src/framework/theme/components/search/styles/search.component.modal-half.scss +++ b/src/framework/theme/components/search/styles/search.component.modal-half.scss @@ -4,6 +4,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ +@import '../../../styles/core/mixins'; + /deep/ nb-layout.modal-half { .layout { transition: transform 0.6s, opacity 0.6s; @@ -49,7 +51,7 @@ font-size: 2.5rem; position: absolute; top: 3rem; - right: 3rem; + @include rtl-prop(right, left, 3rem, auto); display: block; z-index: 100; opacity: 0; diff --git a/src/framework/theme/components/search/styles/search.component.modal-move.scss b/src/framework/theme/components/search/styles/search.component.modal-move.scss index fb7b2d20b6..eb608160e7 100644 --- a/src/framework/theme/components/search/styles/search.component.modal-move.scss +++ b/src/framework/theme/components/search/styles/search.component.modal-move.scss @@ -4,6 +4,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ +@import '../../../styles/core/mixins'; + /deep/ nb-layout.modal-move { .layout { transition: transform 0.5s; @@ -38,7 +40,7 @@ button { position: absolute; top: 3rem; - right: 3rem; + @include rtl-prop(right, left, 3rem, auto); font-size: 2.5rem; opacity: 0; transition: opacity 0.5s; diff --git a/src/framework/theme/components/search/styles/search.component.modal-zoomin.scss b/src/framework/theme/components/search/styles/search.component.modal-zoomin.scss index 85f7df20f9..176383857e 100644 --- a/src/framework/theme/components/search/styles/search.component.modal-zoomin.scss +++ b/src/framework/theme/components/search/styles/search.component.modal-zoomin.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 { button { margin: 0; @@ -98,7 +100,7 @@ button { position: absolute; top: 3rem; - right: 3rem; + @include rtl-prop(right, left, 3rem, auto); font-size: 2.5rem; } From f1708d8f977b96d38dc451ad2d5bc38d779d3d17 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 21:25:20 +0300 Subject: [PATCH 13/89] refactor(badge): add host pseudo class to isolate styles --- src/framework/theme/components/badge/badge.component.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/framework/theme/components/badge/badge.component.scss b/src/framework/theme/components/badge/badge.component.scss index 75e2aa4e9a..829f3ff572 100644 --- a/src/framework/theme/components/badge/badge.component.scss +++ b/src/framework/theme/components/badge/badge.component.scss @@ -6,7 +6,7 @@ @import '../../styles/core/mixins'; -.nb-badge { +:host .nb-badge { position: absolute; padding: 0.25em 0.4em; font-size: 75%; @@ -21,9 +21,9 @@ &.bottom { bottom: 0; } &.start { - @include rtl-prop(left, right, 0, none); + @include rtl-prop(left, right, 0, auto); } &.end { - @include rtl-prop(right, left, 0, none); + @include rtl-prop(right, left, 0, auto); } } From 6e94e9178517d988fc2f0fa3bbb8bce60f919ebf Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 2 Apr 2018 21:44:33 +0300 Subject: [PATCH 14/89] feat(rtl): add rtl styles for user component --- .../theme/components/user/user.component.scss | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/framework/theme/components/user/user.component.scss b/src/framework/theme/components/user/user.component.scss index 06c9950077..294105ccee 100644 --- a/src/framework/theme/components/user/user.component.scss +++ b/src/framework/theme/components/user/user.component.scss @@ -4,37 +4,39 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ +@import '../../styles/core/mixins'; + :host { display: flex; -} -.user-container { - position: relative; - display: flex; - align-items: center; -} + .user-container { + position: relative; + display: flex; + align-items: center; + } -.user-picture { - position: relative; - border-radius: 50%; - flex-shrink: 0; + .user-picture { + position: relative; + border-radius: 50%; + flex-shrink: 0; - &.image { - background-size: cover; - background-repeat: no-repeat; - } + &.image { + background-size: cover; + background-repeat: no-repeat; + } - &.background { - display: flex; - align-items: center; - justify-content: center; + &.background { + display: flex; + align-items: center; + justify-content: center; + } } -} -.user-title { - font-size: 0.75rem; -} + .user-title { + font-size: 0.75rem; + } -.info-container { - margin-left: 0.5rem; + .info-container { + @include rtl-prop(margin-left, margin-right, 0.5rem, 0); + } } From d941631cd3eac0b4503c09db45e43fca8f7a5de0 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Tue, 3 Apr 2018 09:49:22 +0300 Subject: [PATCH 15/89] feat(user-component): align text right for rtl layout --- src/framework/theme/components/user/user.component.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/framework/theme/components/user/user.component.scss b/src/framework/theme/components/user/user.component.scss index 294105ccee..fc4962963d 100644 --- a/src/framework/theme/components/user/user.component.scss +++ b/src/framework/theme/components/user/user.component.scss @@ -36,6 +36,11 @@ font-size: 0.75rem; } + .user-name, + .user-title { + @include rtl-only(text-align, right); + } + .info-container { @include rtl-prop(margin-left, margin-right, 0.5rem, 0); } From 63e0b33d36010bf4c59b3ae53d2460f3230a5428 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Tue, 3 Apr 2018 13:14:01 +0300 Subject: [PATCH 16/89] feat(rtl): add sidebar rtl styles BREAKING CHANGE: change physical left, right properties to logical start, end respectively --- e2e/sidebar-one.e2e-spec.ts | 6 ++--- e2e/sidebar-two.e2e-spec.ts | 6 ++--- e2e/sidebar.e2e-spec.ts | 6 ++--- .../theme-change-test.component.ts | 2 +- .../theme-dynamic-test.component.ts | 2 +- .../sidebar-test-one.component.ts | 2 +- .../sidebar-test-three.component.ts | 2 +- .../sidebar-test-two.component.ts | 2 +- .../sidebar-test/sidebar-test.component.ts | 12 ++++----- .../components/layout/layout.component.scss | 2 +- .../sidebar/_sidebar.component.theme.scss | 24 ++++++++--------- .../components/sidebar/sidebar.component.scss | 10 ++++--- .../components/sidebar/sidebar.component.ts | 26 +++++++++---------- 13 files changed, 51 insertions(+), 51 deletions(-) diff --git a/e2e/sidebar-one.e2e-spec.ts b/e2e/sidebar-one.e2e-spec.ts index 81f779e6db..2b3bc89d82 100644 --- a/e2e/sidebar-one.e2e-spec.ts +++ b/e2e/sidebar-one.e2e-spec.ts @@ -27,14 +27,14 @@ describe('nb-sidebar-one', () => { }); }); - it('should render sidebar default sidebar at left', () => { + it('should render sidebar default sidebar at start', () => { element.all(by.css('nb-sidebar')).get(0).getCssValue('order').then(value => { expect(value).toMatch('0'); }); }); - it('should render right sidebar at right', () => { - element(by.css('nb-sidebar[right]')).getCssValue('order').then(value => { + it('should render end sidebar at end', () => { + element(by.css('nb-sidebar[end]')).getCssValue('order').then(value => { expect(value).toMatch('2'); }); }); diff --git a/e2e/sidebar-two.e2e-spec.ts b/e2e/sidebar-two.e2e-spec.ts index 1b817bf013..c375aaba75 100644 --- a/e2e/sidebar-two.e2e-spec.ts +++ b/e2e/sidebar-two.e2e-spec.ts @@ -22,7 +22,7 @@ describe('nb-sidebar-two', () => { // }); // }); - it('should render left non-fixed sidebar height minus header', () => { + it('should render start non-fixed sidebar height minus header', () => { Promise.all([ element(by.css('nb-layout')).getSize(), element(by.css('nb-layout-header')).getSize(), @@ -38,8 +38,8 @@ describe('nb-sidebar-two', () => { }); }); - it('should render fixed right sidebar at right', () => { - element(by.css('nb-sidebar[right]')).getCssValue('right').then(value => { + it('should render fixed end sidebar at end', () => { + element(by.css('nb-sidebar[end]')).getCssValue('right').then(value => { expect(value).toMatch('0'); }); }); diff --git a/e2e/sidebar.e2e-spec.ts b/e2e/sidebar.e2e-spec.ts index 03a06ade57..217e8118f5 100644 --- a/e2e/sidebar.e2e-spec.ts +++ b/e2e/sidebar.e2e-spec.ts @@ -26,7 +26,7 @@ describe('nb-sidebar', () => { it('should open/close sidebar', () => { - const button = element(by.css('#collapse-left')); + const button = element(by.css('#collapse-start')); const sidebar = element(by.css('nb-sidebar[fixed]')); button.click().then(() => { @@ -56,8 +56,8 @@ describe('nb-sidebar', () => { it('should open/compact sidebar', () => { - const button = element(by.css('#collapse-right')); - const sidebar = element(by.css('nb-sidebar[right]')); + const button = element(by.css('#collapse-end')); + const sidebar = element(by.css('nb-sidebar[end]')); button.click().then(() => { return browser.driver.wait(() => { diff --git a/src/app/layout-test/theme-change-test.component.ts b/src/app/layout-test/theme-change-test.component.ts index d46493d7e5..9d3ecf8303 100644 --- a/src/app/layout-test/theme-change-test.component.ts +++ b/src/app/layout-test/theme-change-test.component.ts @@ -16,7 +16,7 @@ import { NbThemeService } from '@nebular/theme'; - + Sidebar content diff --git a/src/app/layout-test/theme-dynamic-test.component.ts b/src/app/layout-test/theme-dynamic-test.component.ts index 11119dab83..7e1c3cbc85 100644 --- a/src/app/layout-test/theme-dynamic-test.component.ts +++ b/src/app/layout-test/theme-dynamic-test.component.ts @@ -20,7 +20,7 @@ import { NbDynamicToAddComponent } from '../dynamic.component'; - + Sidebar content diff --git a/src/app/sidebar-test/sidebar-test-one.component.ts b/src/app/sidebar-test/sidebar-test-one.component.ts index d61c08dd56..ea20fa5e0c 100644 --- a/src/app/sidebar-test/sidebar-test-one.component.ts +++ b/src/app/sidebar-test/sidebar-test-one.component.ts @@ -21,7 +21,7 @@ import { Component } from '@angular/core'; Left - + Right diff --git a/src/app/sidebar-test/sidebar-test-three.component.ts b/src/app/sidebar-test/sidebar-test-three.component.ts index 54fa40371e..9c2e6b5271 100644 --- a/src/app/sidebar-test/sidebar-test-three.component.ts +++ b/src/app/sidebar-test/sidebar-test-three.component.ts @@ -24,7 +24,7 @@ import { Component } from '@angular/core'; Left - + Right diff --git a/src/app/sidebar-test/sidebar-test-two.component.ts b/src/app/sidebar-test/sidebar-test-two.component.ts index 9f0ab15a2e..0a746bfc74 100644 --- a/src/app/sidebar-test/sidebar-test-two.component.ts +++ b/src/app/sidebar-test/sidebar-test-two.component.ts @@ -24,7 +24,7 @@ import { Component } from '@angular/core'; Left - + Right diff --git a/src/app/sidebar-test/sidebar-test.component.ts b/src/app/sidebar-test/sidebar-test.component.ts index 9b78404fcf..365b793fcd 100644 --- a/src/app/sidebar-test/sidebar-test.component.ts +++ b/src/app/sidebar-test/sidebar-test.component.ts @@ -22,14 +22,14 @@ import { NbSidebarService } from '@nebular/theme'; Akveo - - + + - + - + Some Header {{ content }} @@ -58,11 +58,11 @@ export class NbSidebarTestComponent implements OnInit { constructor(private sidebarService: NbSidebarService) { } collapseLeft() { - this.sidebarService.toggle(false, 'left'); + this.sidebarService.toggle(false, 'start'); } collapseRight() { - this.sidebarService.toggle(true, 'right'); + this.sidebarService.toggle(true, 'end'); } ngOnInit() { diff --git a/src/framework/theme/components/layout/layout.component.scss b/src/framework/theme/components/layout/layout.component.scss index f903cad49d..fbe11d95d7 100644 --- a/src/framework/theme/components/layout/layout.component.scss +++ b/src/framework/theme/components/layout/layout.component.scss @@ -39,7 +39,7 @@ /deep/ nb-sidebar { order: 0; - &.right { + &.end { order: 2; } diff --git a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss index ef23c36243..dd9a970d63 100644 --- a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss +++ b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss @@ -75,7 +75,7 @@ &::before { position: absolute; content: ''; - left: 0; + @include rtl-prop(left, right, 0, auto); top: 0; height: 100%; width: 4px; @@ -115,30 +115,28 @@ } // we need to pull the content - &.left.fixed ~ .content { - margin-left: nb-theme(sidebar-width-compact); + &.start.fixed ~ .content { + @include rtl-prop(margin-left, margin-right, nb-theme(sidebar-width-compact), 0); } - &.fixed.right ~ .content { - margin-left: 0; - margin-right: nb-theme(sidebar-width-compact); + &.fixed.end ~ .content { + @include rtl-prop(margin-right, margin-left, nb-theme(sidebar-width-compact), 0); } - &.left.fixed ~ .content.center { - padding-left: nb-theme(sidebar-width-compact); + &.start.fixed ~ .content.center { + @include rtl-prop(padding-left, padding-right, nb-theme(sidebar-width-compact), 0); } - &.fixed.right ~ .content.center { - padding-left: 0; - padding-right: nb-theme(sidebar-width-compact); + &.fixed.end ~ .content.center { + @include rtl-prop(padding-right, padding-left, nb-theme(sidebar-width-compact), 0); } } - &.fixed.left.collapsed + .content { + &.fixed.start.collapsed + .content { margin-left: 0; } - &.fixed.right.collapsed + .content { + &.fixed.end.collapsed + .content { margin-right: 0; } diff --git a/src/framework/theme/components/sidebar/sidebar.component.scss b/src/framework/theme/components/sidebar/sidebar.component.scss index 6471235f2e..a16fe0a9ff 100644 --- a/src/framework/theme/components/sidebar/sidebar.component.scss +++ b/src/framework/theme/components/sidebar/sidebar.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 { display: flex; flex-direction: column; @@ -25,7 +27,7 @@ flex-direction: column; } - &.right { + &.end { order: 4; margin-right: 0; margin-left: auto; @@ -39,10 +41,10 @@ top: 0; bottom: 0; - left: 0; + @include rtl-prop(left, right, 0, auto); - &.right { - right: 0; + &.end { + @include rtl-prop(right, left, 0, auto); } } diff --git a/src/framework/theme/components/sidebar/sidebar.component.ts b/src/framework/theme/components/sidebar/sidebar.component.ts index 98a56c66ba..76743d4c7d 100644 --- a/src/framework/theme/components/sidebar/sidebar.component.ts +++ b/src/framework/theme/components/sidebar/sidebar.component.ts @@ -47,7 +47,7 @@ export class NbSidebarFooterComponent { /** * Layout sidebar component. * - * Sidebar can be place on the left or the right side of the layout, can be fixed (shown above the content) + * Sidebar can be place on the start or the end side of the layout, can be fixed (shown above the content) * or can push the layout when opened. * * There are three states - `expanded`, `collapsed`, `compacted`. @@ -63,10 +63,10 @@ export class NbSidebarFooterComponent { * * ``` * - * @example Example of fixed sidebar located on the left side, initially collapsed. + * @example Example of fixed sidebar located on the start side, initially collapsed. * * ``` - * + * * Header * * Sidebar content, menu or another component here. @@ -121,8 +121,8 @@ export class NbSidebarComponent implements OnInit, OnDestroy { private alive = true; @HostBinding('class.fixed') fixedValue: boolean = false; - @HostBinding('class.right') rightValue: boolean = false; - @HostBinding('class.left') leftValue: boolean = true; + @HostBinding('class.start') startValue: boolean = true; + @HostBinding('class.end') endValue: boolean = false; // TODO: rename stateValue to state (take a look to the card component) @HostBinding('class.expanded') @@ -139,23 +139,23 @@ export class NbSidebarComponent implements OnInit, OnDestroy { } /** - * Places sidebar on the left side + * Places sidebar on the start side * @type {boolean} */ @Input() - set right(val: boolean) { - this.rightValue = convertToBoolProperty(val); - this.leftValue = !this.rightValue; + set start(val: boolean) { + this.startValue = convertToBoolProperty(val); + this.endValue = !this.startValue; } /** - * Places sidebar on the right side + * Places sidebar on the end side * @type {boolean} */ @Input() - set left(val: boolean) { - this.leftValue = convertToBoolProperty(val); - this.rightValue = !this.leftValue; + set end(val: boolean) { + this.endValue = convertToBoolProperty(val); + this.startValue = !this.endValue; } /** From e011923abf8f242dae614c23d618d70561f5fd6a Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Tue, 3 Apr 2018 14:56:34 +0300 Subject: [PATCH 17/89] feat(rtl): align menu item text to right in rtl layout --- src/framework/theme/components/menu/menu.component.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/framework/theme/components/menu/menu.component.scss b/src/framework/theme/components/menu/menu.component.scss index 18d504465a..4bcbdbea6a 100644 --- a/src/framework/theme/components/menu/menu.component.scss +++ b/src/framework/theme/components/menu/menu.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 /deep/ { display: block; @@ -22,6 +24,7 @@ .menu-title { flex: 1; + @include rtl-only(text-align, right); } } } From d9c05b88fe0b53fcc7726673c3d6687340fb70f4 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Tue, 3 Apr 2018 15:07:25 +0300 Subject: [PATCH 18/89] feat(rtl): add mirroring styles for sidebar --- src/framework/theme/components/sidebar/sidebar.component.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/components/sidebar/sidebar.component.scss b/src/framework/theme/components/sidebar/sidebar.component.scss index a16fe0a9ff..9b9e7dccb6 100644 --- a/src/framework/theme/components/sidebar/sidebar.component.scss +++ b/src/framework/theme/components/sidebar/sidebar.component.scss @@ -29,8 +29,8 @@ &.end { order: 4; - margin-right: 0; - margin-left: auto; + @include rtl-prop(margin-right, margin-left, 0, auto); + @include rtl-prop(margin-left, margin-right, auto, 0); } // TODO: in this case this will won't work when header is not fixed and sidebar is From 723873ae7a8c95fc11289a277705e3be822a6936 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Wed, 4 Apr 2018 14:52:06 +0300 Subject: [PATCH 19/89] refactor(rtl): use 'auto' to reset position properties 'unset' value isn't supported by IE11 --- .../components/card/flip-card/_flip-card.component.theme.scss | 2 +- .../theme/components/checkbox/_checkbox.component.theme.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss b/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss index 52b5a2d2bc..f5ae8ac829 100644 --- a/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss +++ b/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss @@ -6,6 +6,6 @@ } .flipcard-body .front-container { - @include rtl-prop(margin-right, margin-left, -100%, unset); + @include rtl-prop(margin-right, margin-left, -100%, auto); } } diff --git a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss index b10c0fb03a..8ef91697be 100644 --- a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss +++ b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss @@ -60,7 +60,7 @@ position: absolute; top: 50%; transform: translateY(-50%); - @include rtl-prop(left, right, 0, unset); + @include rtl-prop(left, right, 0, auto); flex: none; display: flex; justify-content: center; From 3aa18977462ec05f7b28c9a1dc070f1ba116ccc2 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Wed, 4 Apr 2018 17:21:35 +0300 Subject: [PATCH 20/89] fix(popover): set initial top, left position In rtl layout, popover positioned outside of viewport if 'left' set to 'auto'. In such case, content could shrink, so we'll calculate position based on dimentions, that would differ from those, that we'll have when it rendered inside a viewport. With 'left' equals to '0' popover should always feet viewport and dimentions will not change. Details: https://www.w3.org/TR/CSS2/visuren.html#propdef-left https://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width --- src/framework/theme/components/popover/popover.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/components/popover/popover.component.ts b/src/framework/theme/components/popover/popover.component.ts index ffce5fe788..1183fdff0c 100644 --- a/src/framework/theme/components/popover/popover.component.ts +++ b/src/framework/theme/components/popover/popover.component.ts @@ -64,11 +64,11 @@ export class NbPopoverComponent { @Input() @HostBinding('style.top.px') - positionTop: number; + positionTop: number = 0; @Input() @HostBinding('style.left.px') - positionLeft: number; + positionLeft: number = 0; /** * If content type is TemplateRef we're passing context as template outlet param. From 14091f57ae6651ad27a3d7735c5f4ce412c7ff40 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Wed, 4 Apr 2018 17:28:25 +0300 Subject: [PATCH 21/89] style: prefix public variables with 'Nb' --- .../theme/services/direction.service.ts | 16 ++++++++-------- src/framework/theme/theme.module.ts | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index 4a8d701fd8..5b60a3a0ab 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -1,27 +1,27 @@ import { InjectionToken, Optional, Inject, Injectable } from '@angular/core'; import { NbDocument } from '../theme.options'; -export type Direction = 'ltr' | 'rtl'; +export type NbDirection = 'ltr' | 'rtl'; -export const LAYOUT_DIRECTION = new InjectionToken('Flow direction'); +export const NB_LAYOUT_DIRECTION = new InjectionToken('Layout direction'); @Injectable() export class NbDirectionService { - dir: Direction; + dir: NbDirection; constructor( private document: NbDocument, - @Optional() @Inject(LAYOUT_DIRECTION) dir = 'ltr', + @Optional() @Inject(NB_LAYOUT_DIRECTION) dir = 'ltr', ) { - this.dir = dir; - this.setDirection(dir); + this.dir = dir; + this.setDirection(dir); } - getDirection(): Direction { + getDirection(): NbDirection { return this.dir; } - setDirection(dir: Direction) { + setDirection(dir: NbDirection) { this.dir = dir; this.document.dir = this.dir; } diff --git a/src/framework/theme/theme.module.ts b/src/framework/theme/theme.module.ts index f2b1727a0f..60d1c409fb 100644 --- a/src/framework/theme/theme.module.ts +++ b/src/framework/theme/theme.module.ts @@ -25,7 +25,7 @@ import { NbMediaBreakpoint, NbMediaBreakpointsService, } from './services/breakpoints.service'; -import { NbDirectionService, Direction, LAYOUT_DIRECTION } from './services/direction.service'; +import { NbDirectionService, NbDirection, NB_LAYOUT_DIRECTION } from './services/direction.service'; export function nbWindowFactory() { return window; @@ -53,7 +53,7 @@ export class NbThemeModule { static forRoot(nbThemeOptions: NbThemeOptions, nbJSThemes?: NbJSThemeOptions[], nbMediaBreakpoints?: NbMediaBreakpoint[], - layoutDirection?: Direction): ModuleWithProviders { + layoutDirection?: NbDirection): ModuleWithProviders { return { ngModule: NbThemeModule, @@ -68,11 +68,11 @@ export class NbThemeModule { NbThemeService, NbMediaBreakpointsService, NbSpinnerService, - { provide: LAYOUT_DIRECTION, useValue: layoutDirection || 'ltr' }, + { provide: NB_LAYOUT_DIRECTION, useValue: layoutDirection || 'ltr' }, { provide: NbDirectionService, useClass: NbDirectionService, - deps: [ NbDocument, LAYOUT_DIRECTION ], + deps: [ NbDocument, NB_LAYOUT_DIRECTION ], }, ], }; From c2f6138eb40c19293b27893de8378a75381e673d Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 13:11:55 +0300 Subject: [PATCH 22/89] style: simplify provider entry --- src/framework/theme/theme.module.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/framework/theme/theme.module.ts b/src/framework/theme/theme.module.ts index 60d1c409fb..bb83ff9cd4 100644 --- a/src/framework/theme/theme.module.ts +++ b/src/framework/theme/theme.module.ts @@ -69,11 +69,7 @@ export class NbThemeModule { NbMediaBreakpointsService, NbSpinnerService, { provide: NB_LAYOUT_DIRECTION, useValue: layoutDirection || 'ltr' }, - { - provide: NbDirectionService, - useClass: NbDirectionService, - deps: [ NbDocument, NB_LAYOUT_DIRECTION ], - }, + NbDirectionService, ], }; } From 29a82432dda315c8adc1d0037506ada0c59def77 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 14:32:06 +0300 Subject: [PATCH 23/89] style: rename service, use enum instead of type --- .../theme/services/direction.service.ts | 21 +++++++++++-------- src/framework/theme/theme.module.ts | 8 +++---- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index 5b60a3a0ab..f9f08bf5e5 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -1,27 +1,30 @@ import { InjectionToken, Optional, Inject, Injectable } from '@angular/core'; import { NbDocument } from '../theme.options'; -export type NbDirection = 'ltr' | 'rtl'; +export enum NbLayoutDirection { + LTR = 'ltr', + RTL = 'rtl', +}; -export const NB_LAYOUT_DIRECTION = new InjectionToken('Layout direction'); +export const NB_LAYOUT_DIRECTION = new InjectionToken('Layout direction'); @Injectable() -export class NbDirectionService { - dir: NbDirection; +export class NbLayoutDirectionService { + private dir: NbLayoutDirection; constructor( private document: NbDocument, - @Optional() @Inject(NB_LAYOUT_DIRECTION) dir = 'ltr', + @Optional() @Inject(NB_LAYOUT_DIRECTION) dir = NbLayoutDirection.LTR, ) { - this.dir = dir; - this.setDirection(dir); + this.dir = dir; + this.setDirection(dir); } - getDirection(): NbDirection { + getDirection(): NbLayoutDirection { return this.dir; } - setDirection(dir: NbDirection) { + setDirection(dir: NbLayoutDirection) { this.dir = dir; this.document.dir = this.dir; } diff --git a/src/framework/theme/theme.module.ts b/src/framework/theme/theme.module.ts index bb83ff9cd4..f8dd9d67e8 100644 --- a/src/framework/theme/theme.module.ts +++ b/src/framework/theme/theme.module.ts @@ -25,7 +25,7 @@ import { NbMediaBreakpoint, NbMediaBreakpointsService, } from './services/breakpoints.service'; -import { NbDirectionService, NbDirection, NB_LAYOUT_DIRECTION } from './services/direction.service'; +import { NbLayoutDirectionService, NbLayoutDirection, NB_LAYOUT_DIRECTION } from './services/direction.service'; export function nbWindowFactory() { return window; @@ -53,7 +53,7 @@ export class NbThemeModule { static forRoot(nbThemeOptions: NbThemeOptions, nbJSThemes?: NbJSThemeOptions[], nbMediaBreakpoints?: NbMediaBreakpoint[], - layoutDirection?: NbDirection): ModuleWithProviders { + layoutDirection?: NbLayoutDirection): ModuleWithProviders { return { ngModule: NbThemeModule, @@ -68,8 +68,8 @@ export class NbThemeModule { NbThemeService, NbMediaBreakpointsService, NbSpinnerService, - { provide: NB_LAYOUT_DIRECTION, useValue: layoutDirection || 'ltr' }, - NbDirectionService, + { provide: NB_LAYOUT_DIRECTION, useValue: layoutDirection || NbLayoutDirection.LTR }, + NbLayoutDirectionService, ], }; } From 3a202da7173c858d865f5d785ddaabb7a9b9ee0d Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 14:50:49 +0300 Subject: [PATCH 24/89] feat(layout-direction-service): add helper properties --- src/framework/theme/services/direction.service.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index f9f08bf5e5..192d5f54ac 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -20,6 +20,14 @@ export class NbLayoutDirectionService { this.setDirection(dir); } + public get isLtr() { + return this.dir === NbLayoutDirection.LTR; + } + + public get isRtl() { + return this.dir === NbLayoutDirection.RTL; + } + getDirection(): NbLayoutDirection { return this.dir; } From 2493320b5f9089ff7bc47298befca7f2312988f5 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 15:50:17 +0300 Subject: [PATCH 25/89] refactor(layout-direction-service): create property in constructor --- src/framework/theme/services/direction.service.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index 192d5f54ac..07c23ed237 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -10,11 +10,9 @@ export const NB_LAYOUT_DIRECTION = new InjectionToken('Layout @Injectable() export class NbLayoutDirectionService { - private dir: NbLayoutDirection; - constructor( private document: NbDocument, - @Optional() @Inject(NB_LAYOUT_DIRECTION) dir = NbLayoutDirection.LTR, + @Optional() @Inject(NB_LAYOUT_DIRECTION) private dir = NbLayoutDirection.LTR, ) { this.dir = dir; this.setDirection(dir); From 90179faee41b3e56a308a397a4c34b7fe51bb4b3 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 16:06:57 +0300 Subject: [PATCH 26/89] feat(rtl): add start, end options for popover component --- .../context-menu/context-menu.directive.ts | 5 +- .../theme/components/popover/helpers/model.ts | 5 ++ .../components/popover/popover.directive.ts | 59 +++++++++++++------ .../examples/popover-example.component.ts | 6 ++ 4 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/framework/theme/components/context-menu/context-menu.directive.ts b/src/framework/theme/components/context-menu/context-menu.directive.ts index 5cbee38ee4..fcc91e3381 100644 --- a/src/framework/theme/components/context-menu/context-menu.directive.ts +++ b/src/framework/theme/components/context-menu/context-menu.directive.ts @@ -16,6 +16,7 @@ import { NbContextMenuComponent } from './context-menu.component'; import { NbPositioningHelper } from '../popover/helpers/positioning.helper'; import { NbAdjustmentHelper } from '../popover/helpers/adjustment.helper'; import { NbTriggerHelper } from '../popover/helpers/trigger.helper'; +import { NbLayoutDirectionService } from '../../services/direction.service'; /** * Full featured context menu directive. @@ -97,7 +98,8 @@ export class NbContextMenuDirective implements OnInit, OnDestroy { positioningHelper: NbPositioningHelper, adjustmentHelper: NbAdjustmentHelper, triggerHelper: NbTriggerHelper, - @Inject(PLATFORM_ID) platformId) { + @Inject(PLATFORM_ID) platformId, + directionService: NbLayoutDirectionService) { /** * Initialize popover with all the important inputs. * */ @@ -108,6 +110,7 @@ export class NbContextMenuDirective implements OnInit, OnDestroy { adjustmentHelper, triggerHelper, platformId, + directionService, ); this.popover.content = NbContextMenuComponent; this.popover.placement = NbPopoverPlacement.BOTTOM; diff --git a/src/framework/theme/components/popover/helpers/model.ts b/src/framework/theme/components/popover/helpers/model.ts index 5c34569de6..9c2529ab00 100644 --- a/src/framework/theme/components/popover/helpers/model.ts +++ b/src/framework/theme/components/popover/helpers/model.ts @@ -29,6 +29,11 @@ export enum NbPopoverPlacement { RIGHT = 'right', } +export enum NbPopoverLogicalPlacement { + START = 'start', + END = 'end', +} + /** * NbPopoverMode describes when to trigger show and hide methods of the popover. * */ diff --git a/src/framework/theme/components/popover/popover.directive.ts b/src/framework/theme/components/popover/popover.directive.ts index 592db916f4..5629086341 100644 --- a/src/framework/theme/components/popover/popover.directive.ts +++ b/src/framework/theme/components/popover/popover.directive.ts @@ -14,9 +14,16 @@ import { takeWhile } from 'rxjs/operators/takeWhile'; import { NbPositioningHelper } from './helpers/positioning.helper'; import { NbPopoverComponent, NbPopoverContent } from './popover.component'; import { NbThemeService } from '../../services/theme.service'; +import { NbLayoutDirectionService } from '../../services/direction.service'; import { NbAdjustmentHelper } from './helpers/adjustment.helper'; import { NbTriggerHelper } from './helpers/trigger.helper'; -import { NbPopoverAdjustment, NbPopoverMode, NbPopoverPlacement, NbPopoverPosition } from './helpers/model'; +import { + NbPopoverAdjustment, + NbPopoverMode, + NbPopoverPlacement, + NbPopoverPosition, + NbPopoverLogicalPlacement, +} from './helpers/model'; /** * Powerful popover directive, which provides the best UX for your users. @@ -61,13 +68,13 @@ import { NbPopoverAdjustment, NbPopoverMode, NbPopoverPlacement, NbPopoverPositi * ``` * * */ - /* - * - * TODO - * Rendering strategy have to be refactored. - * For now directive creates and deletes popover container each time. - * I think we can handle this slightly smarter and show/hide in any situations. - */ +/* +* +* TODO +* Rendering strategy have to be refactored. +* For now directive creates and deletes popover container each time. +* I think we can handle this slightly smarter and show/hide in any situations. +*/ @Directive({ selector: '[nbPopover]' }) export class NbPopoverDirective implements OnInit, OnDestroy { @@ -86,10 +93,10 @@ export class NbPopoverDirective implements OnInit, OnDestroy { /** * Position will be calculated relatively host element based on the placement. - * Can be top, right, bottom and left. + * Can be top, right, bottom, left, start or end. * */ @Input('nbPopoverPlacement') - placement: NbPopoverPlacement = NbPopoverPlacement.TOP; + placement: NbPopoverPlacement | NbPopoverLogicalPlacement = NbPopoverPlacement.TOP; /** * Container placement will be changes automatically based on this strategy if container can't fit view port. @@ -149,6 +156,7 @@ export class NbPopoverDirective implements OnInit, OnDestroy { private adjustmentHelper: NbAdjustmentHelper, private triggerHelper: NbTriggerHelper, @Inject(PLATFORM_ID) private platformId, + private layoutDirectionService: NbLayoutDirectionService, ) {} ngOnInit() { @@ -287,7 +295,7 @@ export class NbPopoverDirective implements OnInit, OnDestroy { /* * Set container position. * */ - private patchPopoverPosition({ top: top, left: left }) { + private patchPopoverPosition({ top, left }) { this.container.positionTop = top; this.container.positionLeft = left; } @@ -311,7 +319,25 @@ export class NbPopoverDirective implements OnInit, OnDestroy { return this.calcAdjustment(placed, host); } - return this.calcPosition(placed, host); + return { + position: this.calcPosition(placed, host), + placement: this.physicalPlacement, + }; + } + + /* + * Maps logical position to physical according to current layout direction. + * */ + private get physicalPlacement(): NbPopoverPlacement { + const isLtr = this.layoutDirectionService.isLtr; + if (this.placement === NbPopoverLogicalPlacement.START) { + return isLtr ? NbPopoverPlacement.LEFT : NbPopoverPlacement.RIGHT; + } + if (this.placement === NbPopoverLogicalPlacement.END) { + return isLtr ? NbPopoverPlacement.RIGHT : NbPopoverPlacement.LEFT; + } + + return this.placement; } /* @@ -319,17 +345,14 @@ export class NbPopoverDirective implements OnInit, OnDestroy { * see {@link NbAdjustmentHelper}. * */ private calcAdjustment(placed: ClientRect, host: ClientRect): NbPopoverPosition { - return this.adjustmentHelper.adjust(placed, host, this.placement, this.adjustment) + return this.adjustmentHelper.adjust(placed, host, this.physicalPlacement, this.adjustment); } /* * Calculate position. * see {@link NbPositioningHelper} * */ - private calcPosition(placed: ClientRect, host: ClientRect): NbPopoverPosition { - return { - position: this.positioningHelper.calcPosition(placed, host, this.placement), - placement: this.placement, - } + private calcPosition(placed: ClientRect, host: ClientRect): {top: number, left: number} { + return this.positioningHelper.calcPosition(placed, host, this.physicalPlacement); } } diff --git a/src/playground/examples/popover-example.component.ts b/src/playground/examples/popover-example.component.ts index 37676910cd..25cb8e7aca 100644 --- a/src/playground/examples/popover-example.component.ts +++ b/src/playground/examples/popover-example.component.ts @@ -65,6 +65,12 @@ import { NbDynamicToAddComponent } from '../../app/dynamic.component'; + + From 5b7928fd5e610f0a39d1475e791d742a9e850110 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 16:15:29 +0300 Subject: [PATCH 27/89] refactor(badge): revert badge api changes --- e2e/actions.e2e-spec.ts | 14 +++++++------- e2e/tabset.e2e-spec.ts | 10 +++++----- e2e/user.e2e-spec.ts | 10 +++++----- src/app/actions-test/actions-test.component.ts | 12 ++++++------ src/app/tabset-test/tabset-test.component.ts | 16 ++++++++-------- src/app/user-test/user-test.component.ts | 8 ++++---- .../components/actions/actions.component.ts | 2 +- .../theme/components/badge/badge.component.scss | 16 ++++++++-------- .../theme/components/badge/badge.component.ts | 16 ++++++++-------- .../theme/components/tabset/tabset.component.ts | 2 +- .../theme/components/user/user.component.ts | 2 +- 11 files changed, 54 insertions(+), 54 deletions(-) diff --git a/e2e/actions.e2e-spec.ts b/e2e/actions.e2e-spec.ts index 0c3c33f852..b122558093 100644 --- a/e2e/actions.e2e-spec.ts +++ b/e2e/actions.e2e-spec.ts @@ -19,13 +19,13 @@ describe('nb-action', () => { const badgesConf = { selector: (i) => `nb-card:nth-child(4) nb-actions nb-action:nth-child(${i + 1}) nb-badge > span`, badges: [ - { position: NbBadgeComponent.BOTTOM_START, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, - { position: NbBadgeComponent.TOP_START, status: NbBadgeComponent.STATUS_DANGER, text: badgeText }, - { position: NbBadgeComponent.BOTTOM_END, status: NbBadgeComponent.STATUS_WARNING, text: badgeText }, - { position: NbBadgeComponent.BOTTOM_START, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, - { position: NbBadgeComponent.TOP_END, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, - { position: NbBadgeComponent.TOP_END, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, - { position: NbBadgeComponent.TOP_END, status: NbBadgeComponent.STATUS_PRIMARY, text: badgeText }, + { position: NbBadgeComponent.BOTTOM_LEFT, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, + { position: NbBadgeComponent.TOP_LEFT, status: NbBadgeComponent.STATUS_DANGER, text: badgeText }, + { position: NbBadgeComponent.BOTTOM_RIGHT, status: NbBadgeComponent.STATUS_WARNING, text: badgeText }, + { position: NbBadgeComponent.BOTTOM_LEFT, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, + { position: NbBadgeComponent.TOP_RIGHT, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, + { position: NbBadgeComponent.TOP_RIGHT, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, + { position: NbBadgeComponent.TOP_RIGHT, status: NbBadgeComponent.STATUS_PRIMARY, text: badgeText }, ], }; badgeTests(badgesConf); diff --git a/e2e/tabset.e2e-spec.ts b/e2e/tabset.e2e-spec.ts index 3c8f66afdc..2b48e1209c 100644 --- a/e2e/tabset.e2e-spec.ts +++ b/e2e/tabset.e2e-spec.ts @@ -103,11 +103,11 @@ describe('nb-tabset', () => { const badgesConf = { selector: (i) => `nb-tabset:nth-child(6) > ul > li:nth-child(${i + 1}) > nb-badge > span`, badges: [ - { text: badgeText, status: NbBadgeComponent.STATUS_PRIMARY, position: NbBadgeComponent.TOP_END }, - { text: badgeText, status: NbBadgeComponent.STATUS_INFO, position: NbBadgeComponent.TOP_START }, - { text: badgeText, status: NbBadgeComponent.STATUS_SUCCESS, position: NbBadgeComponent.BOTTOM_END }, - { text: badgeText, status: NbBadgeComponent.STATUS_DANGER, position: NbBadgeComponent.BOTTOM_START }, - { text: badgeText, status: NbBadgeComponent.STATUS_WARNING, position: NbBadgeComponent.BOTTOM_END }, + { text: badgeText, status: NbBadgeComponent.STATUS_PRIMARY, position: NbBadgeComponent.TOP_RIGHT }, + { text: badgeText, status: NbBadgeComponent.STATUS_INFO, position: NbBadgeComponent.TOP_LEFT }, + { text: badgeText, status: NbBadgeComponent.STATUS_SUCCESS, position: NbBadgeComponent.BOTTOM_RIGHT }, + { text: badgeText, status: NbBadgeComponent.STATUS_DANGER, position: NbBadgeComponent.BOTTOM_LEFT }, + { text: badgeText, status: NbBadgeComponent.STATUS_WARNING, position: NbBadgeComponent.BOTTOM_RIGHT }, ], }; badgeTests(badgesConf); diff --git a/e2e/user.e2e-spec.ts b/e2e/user.e2e-spec.ts index d4ad7f8792..309d28ed59 100644 --- a/e2e/user.e2e-spec.ts +++ b/e2e/user.e2e-spec.ts @@ -26,11 +26,11 @@ describe('nb-user', () => { const badgesConf = { selector: (i) => `.test-row:nth-child(${elementsOffset + i + 1}) nb-badge > span`, badges: [ - { position: NbBadgeComponent.TOP_END, status: NbBadgeComponent.STATUS_PRIMARY, text: badgeText }, - { position: NbBadgeComponent.TOP_START, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, - { position: NbBadgeComponent.BOTTOM_END, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, - { position: NbBadgeComponent.BOTTOM_START, status: NbBadgeComponent.STATUS_WARNING, text: badgeText }, - { position: NbBadgeComponent.TOP_START, status: NbBadgeComponent.STATUS_DANGER, text: badgeText }, + { position: NbBadgeComponent.TOP_RIGHT, status: NbBadgeComponent.STATUS_PRIMARY, text: badgeText }, + { position: NbBadgeComponent.TOP_LEFT, status: NbBadgeComponent.STATUS_INFO, text: badgeText }, + { position: NbBadgeComponent.BOTTOM_RIGHT, status: NbBadgeComponent.STATUS_SUCCESS, text: badgeText }, + { position: NbBadgeComponent.BOTTOM_LEFT, status: NbBadgeComponent.STATUS_WARNING, text: badgeText }, + { position: NbBadgeComponent.TOP_LEFT, status: NbBadgeComponent.STATUS_DANGER, text: badgeText }, ], }; badgeTests(badgesConf); diff --git a/src/app/actions-test/actions-test.component.ts b/src/app/actions-test/actions-test.component.ts index 9cdf6989f2..03d73ed097 100644 --- a/src/app/actions-test/actions-test.component.ts +++ b/src/app/actions-test/actions-test.component.ts @@ -88,37 +88,37 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone + [badgePosition]="badge.BOTTOM_LEFT"> diff --git a/src/app/tabset-test/tabset-test.component.ts b/src/app/tabset-test/tabset-test.component.ts index d88828c301..6ad5e624a1 100644 --- a/src/app/tabset-test/tabset-test.component.ts +++ b/src/app/tabset-test/tabset-test.component.ts @@ -82,25 +82,25 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone + [badgePosition]="badge.TOP_LEFT"> Content #2 + [badgePosition]="badge.BOTTOM_RIGHT"> Content #3 + [badgePosition]="badge.BOTTOM_LEFT"> Content #4 + [badgePosition]="badge.BOTTOM_RIGHT"> Content #5 @@ -111,25 +111,25 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone + [badgePosition]="badge.BOTTOM_RIGHT"> Content #2 + [badgePosition]="badge.TOP_LEFT"> Content #3 + [badgePosition]="badge.BOTTOM_LEFT"> Content #4 + [badgePosition]="badge.BOTTOM_RIGHT"> Content #5 diff --git a/src/app/user-test/user-test.component.ts b/src/app/user-test/user-test.component.ts index 7d5bb416da..b29071f220 100644 --- a/src/app/user-test/user-test.component.ts +++ b/src/app/user-test/user-test.component.ts @@ -65,7 +65,7 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone title="Worker" badgeText="29" [badgeStatus]="badge.STATUS_INFO" - [badgePosition]="badge.TOP_START"> + [badgePosition]="badge.TOP_LEFT">
@@ -76,7 +76,7 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone showTitle="false" badgeText="29" [badgeStatus]="badge.STATUS_SUCCESS" - [badgePosition]="badge.BOTTOM_END"> + [badgePosition]="badge.BOTTOM_RIGHT">
@@ -87,7 +87,7 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone title="Worker" badgeText="29" [badgeStatus]="badge.STATUS_WARNING" - [badgePosition]="badge.BOTTOM_START"> + [badgePosition]="badge.BOTTOM_LEFT">
@@ -98,7 +98,7 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone title="Worker" badgeText="29" [badgeStatus]="badge.STATUS_DANGER" - [badgePosition]="badge.TOP_START"> + [badgePosition]="badge.TOP_LEFT">
diff --git a/src/framework/theme/components/actions/actions.component.ts b/src/framework/theme/components/actions/actions.component.ts index d30823fc0b..b43e686e94 100644 --- a/src/framework/theme/components/actions/actions.component.ts +++ b/src/framework/theme/components/actions/actions.component.ts @@ -62,7 +62,7 @@ export class NbActionComponent { /** * Badge position. * Can be set to any class or to one of predefined positions: - * 'top start', 'top end', 'bottom start', 'bottom end' + * 'top left', 'top right', 'bottom left', 'bottom right' * @type string */ @Input() badgePosition: string; diff --git a/src/framework/theme/components/badge/badge.component.scss b/src/framework/theme/components/badge/badge.component.scss index 829f3ff572..1d7e60e7ac 100644 --- a/src/framework/theme/components/badge/badge.component.scss +++ b/src/framework/theme/components/badge/badge.component.scss @@ -17,13 +17,13 @@ vertical-align: baseline; border-radius: 0.25rem; - &.top { top: 0; } - &.bottom { bottom: 0; } + &.top { top: 0; } + &.bottom { bottom: 0; } - &.start { - @include rtl-prop(left, right, 0, auto); - } - &.end { - @include rtl-prop(right, left, 0, auto); - } + &.start { + @include rtl-prop(left, right, 0, auto); + } + &.end { + @include rtl-prop(right, left, 0, auto); + } } diff --git a/src/framework/theme/components/badge/badge.component.ts b/src/framework/theme/components/badge/badge.component.ts index 0375bf72b2..edf98d968c 100644 --- a/src/framework/theme/components/badge/badge.component.ts +++ b/src/framework/theme/components/badge/badge.component.ts @@ -22,10 +22,10 @@ import { Component, Input } from '@angular/core'; * * ``` * - * @example Badge located on the bottom end with warning status: + * @example Badge located on the bottom right with warning status: * * ``` - * + * * * ``` * @@ -46,10 +46,10 @@ import { Component, Input } from '@angular/core'; `, }) export class NbBadgeComponent { - static readonly TOP_START = 'top start'; - static readonly TOP_END = 'top end'; - static readonly BOTTOM_START = 'bottom start'; - static readonly BOTTOM_END = 'bottom end'; + static readonly TOP_LEFT = 'top left'; + static readonly TOP_RIGHT = 'top right'; + static readonly BOTTOM_LEFT = 'bottom left'; + static readonly BOTTOM_RIGHT = 'bottom right'; static readonly STATUS_PRIMARY = 'primary'; static readonly STATUS_INFO = 'info'; @@ -57,7 +57,7 @@ export class NbBadgeComponent { static readonly STATUS_WARNING = 'warning'; static readonly STATUS_DANGER = 'danger'; - positionClass: string = NbBadgeComponent.TOP_END; + positionClass: string = NbBadgeComponent.TOP_RIGHT; colorClass: string = NbBadgeComponent.STATUS_PRIMARY; /** @@ -70,7 +70,7 @@ export class NbBadgeComponent { * Badge position * * Can be set to any class or to one of predefined positions: - * 'top start', 'top end', 'bottom start', 'bottom end' + * 'top left', 'top right', 'bottom left', 'bottom right' * @type string */ @Input() set position(value) { diff --git a/src/framework/theme/components/tabset/tabset.component.ts b/src/framework/theme/components/tabset/tabset.component.ts index 27ee18361f..ceb8a85a5f 100644 --- a/src/framework/theme/components/tabset/tabset.component.ts +++ b/src/framework/theme/components/tabset/tabset.component.ts @@ -78,7 +78,7 @@ export class NbTabComponent { /** * Badge position. * Can be set to any class or to one of predefined positions: - * 'top start', 'top end', 'bottom start', 'bottom end' + * 'top left', 'top right', 'bottom left', 'bottom right' * @type string */ @Input() badgePosition: string; diff --git a/src/framework/theme/components/user/user.component.ts b/src/framework/theme/components/user/user.component.ts index dd4eef2ae7..54dae404ff 100644 --- a/src/framework/theme/components/user/user.component.ts +++ b/src/framework/theme/components/user/user.component.ts @@ -167,7 +167,7 @@ export class NbUserComponent { /** * Badge position. * Can be set to any class or to one of predefined positions: - * 'top start', 'top end', 'bottom start', 'bottom end' + * 'top left', 'top right', 'bottom left', 'bottom right' * @type string */ @Input() badgePosition: string; From 53829016c49c53f885468b37bc264d292d94d7ec Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 17:29:51 +0300 Subject: [PATCH 28/89] refactor(badge): revert badge api changes --- .../theme/components/badge/badge.component.scss | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/framework/theme/components/badge/badge.component.scss b/src/framework/theme/components/badge/badge.component.scss index 1d7e60e7ac..c2d51fbd95 100644 --- a/src/framework/theme/components/badge/badge.component.scss +++ b/src/framework/theme/components/badge/badge.component.scss @@ -18,12 +18,7 @@ border-radius: 0.25rem; &.top { top: 0; } + &.right { right: 0; } &.bottom { bottom: 0; } - - &.start { - @include rtl-prop(left, right, 0, auto); - } - &.end { - @include rtl-prop(right, left, 0, auto); - } + &.left { left: 0; } } From e69f44d4369dcc17c225c2f2258a91c6d2b7ee04 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 18:00:41 +0300 Subject: [PATCH 29/89] feat(rtl): add logical position properties for badge component --- src/app/user-test/user-test.component.ts | 11 +++++++ .../components/actions/actions.component.ts | 3 +- .../theme/components/badge/badge.component.ts | 31 ++++++++++++++----- .../components/tabset/tabset.component.ts | 3 +- .../theme/components/user/user.component.ts | 3 +- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/app/user-test/user-test.component.ts b/src/app/user-test/user-test.component.ts index b29071f220..f0f644c1ef 100644 --- a/src/app/user-test/user-test.component.ts +++ b/src/app/user-test/user-test.component.ts @@ -105,6 +105,17 @@ import { NbBadgeComponent } from 'framework/theme/components/badge/badge.compone
+
+ + +
`, diff --git a/src/framework/theme/components/actions/actions.component.ts b/src/framework/theme/components/actions/actions.component.ts index b43e686e94..fa9be96cb2 100644 --- a/src/framework/theme/components/actions/actions.component.ts +++ b/src/framework/theme/components/actions/actions.component.ts @@ -62,7 +62,8 @@ export class NbActionComponent { /** * Badge position. * Can be set to any class or to one of predefined positions: - * 'top left', 'top right', 'bottom left', 'bottom right' + * 'top left', 'top right', 'bottom left', 'bottom right', + * 'top start', 'top end', 'bottom start', 'bottom end' * @type string */ @Input() badgePosition: string; diff --git a/src/framework/theme/components/badge/badge.component.ts b/src/framework/theme/components/badge/badge.component.ts index edf98d968c..ffb1e0670b 100644 --- a/src/framework/theme/components/badge/badge.component.ts +++ b/src/framework/theme/components/badge/badge.component.ts @@ -5,6 +5,7 @@ */ import { Component, Input } from '@angular/core'; +import { NbLayoutDirectionService } from '../../services/direction.service'; /** * Badge is a simple labeling component. @@ -51,13 +52,17 @@ export class NbBadgeComponent { static readonly BOTTOM_LEFT = 'bottom left'; static readonly BOTTOM_RIGHT = 'bottom right'; + static readonly TOP_START = 'top start'; + static readonly TOP_END = 'top end'; + static readonly BOTTOM_START = 'bottom start'; + static readonly BOTTOM_END = 'bottom end'; + 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'; - positionClass: string = NbBadgeComponent.TOP_RIGHT; colorClass: string = NbBadgeComponent.STATUS_PRIMARY; /** @@ -70,14 +75,11 @@ export class NbBadgeComponent { * Badge position * * Can be set to any class or to one of predefined positions: - * 'top left', 'top right', 'bottom left', 'bottom right' + * 'top left', 'top right', 'bottom left', 'bottom right', + * 'top start', 'top end', 'bottom start', 'bottom end' * @type string */ - @Input() set position(value) { - if (value) { - this.positionClass = value; - } - } + @Input() position: string; /** * Badge status (adds specific styles): @@ -90,4 +92,19 @@ export class NbBadgeComponent { this.colorClass = value; } } + + get positionClass() { + if (!this.position) { + return NbBadgeComponent.TOP_RIGHT; + } + + const { isLtr } = this.layoutDirectionService; + const startValue = isLtr ? 'left' : 'right'; + const endValue = isLtr ? 'right' : 'left'; + return this.position + .replace(/\bstart\b/, startValue) + .replace(/\bend\b/, endValue); + } + + constructor(private layoutDirectionService: NbLayoutDirectionService) {} } diff --git a/src/framework/theme/components/tabset/tabset.component.ts b/src/framework/theme/components/tabset/tabset.component.ts index ceb8a85a5f..f603de082b 100644 --- a/src/framework/theme/components/tabset/tabset.component.ts +++ b/src/framework/theme/components/tabset/tabset.component.ts @@ -78,7 +78,8 @@ export class NbTabComponent { /** * Badge position. * Can be set to any class or to one of predefined positions: - * 'top left', 'top right', 'bottom left', 'bottom right' + * 'top left', 'top right', 'bottom left', 'bottom right', + * 'top start', 'top end', 'bottom start', 'bottom end' * @type string */ @Input() badgePosition: string; diff --git a/src/framework/theme/components/user/user.component.ts b/src/framework/theme/components/user/user.component.ts index 54dae404ff..8b59311a27 100644 --- a/src/framework/theme/components/user/user.component.ts +++ b/src/framework/theme/components/user/user.component.ts @@ -167,7 +167,8 @@ export class NbUserComponent { /** * Badge position. * Can be set to any class or to one of predefined positions: - * 'top left', 'top right', 'bottom left', 'bottom right' + * 'top left', 'top right', 'bottom left', 'bottom right', + * 'top start', 'top end', 'bottom start', 'bottom end' * @type string */ @Input() badgePosition: string; From f9a58488e1d22eca84a5feab9d54b97fdc8f0159 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 18:02:05 +0300 Subject: [PATCH 30/89] style: use destructuring assignment --- src/framework/theme/components/popover/popover.directive.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/theme/components/popover/popover.directive.ts b/src/framework/theme/components/popover/popover.directive.ts index 5629086341..139f261997 100644 --- a/src/framework/theme/components/popover/popover.directive.ts +++ b/src/framework/theme/components/popover/popover.directive.ts @@ -329,7 +329,7 @@ export class NbPopoverDirective implements OnInit, OnDestroy { * Maps logical position to physical according to current layout direction. * */ private get physicalPlacement(): NbPopoverPlacement { - const isLtr = this.layoutDirectionService.isLtr; + const { isLtr } = this.layoutDirectionService; if (this.placement === NbPopoverLogicalPlacement.START) { return isLtr ? NbPopoverPlacement.LEFT : NbPopoverPlacement.RIGHT; } From b241f00237f2ccc3fcad9bf239c2ca4b286eb546 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 18:18:21 +0300 Subject: [PATCH 31/89] refactor(lauout-column): change column position property to logical BREAKING CHANGE: Changing property name to match common style of properties, that can adapt to layout direction. --- src/app/sidebar-test/sidebar-test.component.ts | 2 +- .../theme/components/layout/layout.component.scss | 2 +- src/framework/theme/components/layout/layout.component.ts | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/sidebar-test/sidebar-test.component.ts b/src/app/sidebar-test/sidebar-test.component.ts index 365b793fcd..149b4a8204 100644 --- a/src/app/sidebar-test/sidebar-test.component.ts +++ b/src/app/sidebar-test/sidebar-test.component.ts @@ -34,7 +34,7 @@ import { NbSidebarService } from '@nebular/theme'; {{ content }} - + {{ content }} diff --git a/src/framework/theme/components/layout/layout.component.scss b/src/framework/theme/components/layout/layout.component.scss index fbe11d95d7..7b2c03c9db 100644 --- a/src/framework/theme/components/layout/layout.component.scss +++ b/src/framework/theme/components/layout/layout.component.scss @@ -76,7 +76,7 @@ order: 2; flex: 1 0; min-width: 0; // fix for flexbug https://github.com/philipwalton/flexbugs#flexbug-1 - &.left { + &.start { order: 1; } } diff --git a/src/framework/theme/components/layout/layout.component.ts b/src/framework/theme/components/layout/layout.component.ts index fea6bba90d..6d9f9c5d46 100644 --- a/src/framework/theme/components/layout/layout.component.ts +++ b/src/framework/theme/components/layout/layout.component.ts @@ -43,15 +43,15 @@ import { NbWindow, NbDocument } from '../../theme.options'; }) export class NbLayoutColumnComponent { - @HostBinding('class.left') leftValue: boolean; + @HostBinding('class.start') startValue: boolean; /** - * Move the column to the very left position in the layout. + * Make columnt first in the layout. * @param {boolean} val */ @Input() - set left(val: boolean) { - this.leftValue = convertToBoolProperty(val); + set start(val: boolean) { + this.startValue = convertToBoolProperty(val); } } From 1186ac6f6fcc9646c89478552574ce09d3cdd5c0 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 18:36:54 +0300 Subject: [PATCH 32/89] docs(direction-service): add service documentation --- .../theme/services/direction.service.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index 07c23ed237..d9540fdf68 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -1,13 +1,22 @@ import { InjectionToken, Optional, Inject, Injectable } from '@angular/core'; import { NbDocument } from '../theme.options'; +/** + * Layout direction. + * */ export enum NbLayoutDirection { LTR = 'ltr', RTL = 'rtl', }; +/** + * Layout direction setting injection token. + * */ export const NB_LAYOUT_DIRECTION = new InjectionToken('Layout direction'); +/** + * Layout Direction Service. Allows you to listen to menu events, or to interact with a menu. + */ @Injectable() export class NbLayoutDirectionService { constructor( @@ -18,18 +27,34 @@ export class NbLayoutDirectionService { this.setDirection(dir); } + /** + * Returns true if layout direction set to left to right. + * @returns boolean. + * */ public get isLtr() { return this.dir === NbLayoutDirection.LTR; } + /** + * Returns true if layout direction set to right to left. + * @returns boolean. + * */ public get isRtl() { return this.dir === NbLayoutDirection.RTL; } + /** + * Returns current layout direction. + * @returns NbLayoutDirection. + * */ getDirection(): NbLayoutDirection { return this.dir; } + /** + * Sets layout direction. + * @param dir {NbLayoutDirection} direction to set. + * */ setDirection(dir: NbLayoutDirection) { this.dir = dir; this.document.dir = this.dir; From 05383303baa20fe9d751254f97d8a8d9b7925b31 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 18:38:01 +0300 Subject: [PATCH 33/89] style(direction-service): add types, remove unnecessary cast --- src/framework/theme/services/direction.service.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index d9540fdf68..f0bd43c319 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -24,14 +24,14 @@ export class NbLayoutDirectionService { @Optional() @Inject(NB_LAYOUT_DIRECTION) private dir = NbLayoutDirection.LTR, ) { this.dir = dir; - this.setDirection(dir); + this.setDirection(dir); } /** * Returns true if layout direction set to left to right. * @returns boolean. * */ - public get isLtr() { + public get isLtr(): boolean { return this.dir === NbLayoutDirection.LTR; } @@ -39,7 +39,7 @@ export class NbLayoutDirectionService { * Returns true if layout direction set to right to left. * @returns boolean. * */ - public get isRtl() { + public get isRtl(): boolean { return this.dir === NbLayoutDirection.RTL; } @@ -57,6 +57,6 @@ export class NbLayoutDirectionService { * */ setDirection(dir: NbLayoutDirection) { this.dir = dir; - this.document.dir = this.dir; + this.document.dir = dir; } } From 5786eca31097fb02307b1ace775d4a868026cfa0 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 18:42:18 +0300 Subject: [PATCH 34/89] feat(docs): include directions service docs entry --- docs/structure.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/structure.ts b/docs/structure.ts index 66b2696da1..6e3bd5dbf7 100644 --- a/docs/structure.ts +++ b/docs/structure.ts @@ -418,6 +418,17 @@ export const STRUCTURE = [ }, ], }, + { + type: 'page', + name: 'LayoutDirectionService', + children: [ + { + type: 'block', + block: 'component', + source: 'NbLayoutDirectionService', + }, + ], + }, ], }, { From 6b337a735ea9e85d912cfb1ecf60d309ef191b6e Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 5 Apr 2018 19:04:23 +0300 Subject: [PATCH 35/89] feat(rtl): mirror horizontal paddings for menu items --- src/framework/theme/styles/themes/_cosmic.scss | 2 +- src/framework/theme/styles/themes/_default.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/styles/themes/_cosmic.scss b/src/framework/theme/styles/themes/_cosmic.scss index 46c8ceed86..786d0432c2 100644 --- a/src/framework/theme/styles/themes/_cosmic.scss +++ b/src/framework/theme/styles/themes/_cosmic.scss @@ -84,7 +84,7 @@ $theme: ( menu-submenu-active-bg: rgba(0, 255, 170, 0.25), menu-submenu-active-border-color: color-fg-highlight, menu-submenu-active-shadow: 0 2px 12px 0 rgba(0, 255, 170, 0.25), - menu-item-padding: 0.25rem 1rem 0.25rem 0.75rem, + menu-item-padding: 0.25rem 1rem 0.75rem, menu-item-separator: transparent, btn-hero-shadow: 0 4px 10px 0 rgba(33, 7, 77, 0.5), diff --git a/src/framework/theme/styles/themes/_default.scss b/src/framework/theme/styles/themes/_default.scss index 1a97531c76..e0fc71c3c6 100644 --- a/src/framework/theme/styles/themes/_default.scss +++ b/src/framework/theme/styles/themes/_default.scss @@ -181,7 +181,7 @@ $theme: ( menu-group-font-size: 0.875rem, menu-group-fg: color-fg, menu-group-padding: 1rem 1.25rem, - menu-item-padding: 0.675rem 1rem 0.675rem 0.75rem, + menu-item-padding: 0.675rem 1rem 0.75rem, menu-item-separator: separator, menu-icon-font-size: 2.5rem, menu-icon-margin: 0 0.5rem 0 0, From 5506186bec0df9a20e90c4c7c6a6a6bded38e78a Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 6 Apr 2018 10:22:34 +0300 Subject: [PATCH 36/89] style(direction-service): rename dir to direction --- .../theme/services/direction.service.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index f0bd43c319..b9bc733fd9 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -21,10 +21,9 @@ export const NB_LAYOUT_DIRECTION = new InjectionToken('Layout export class NbLayoutDirectionService { constructor( private document: NbDocument, - @Optional() @Inject(NB_LAYOUT_DIRECTION) private dir = NbLayoutDirection.LTR, + @Optional() @Inject(NB_LAYOUT_DIRECTION) private direction = NbLayoutDirection.LTR, ) { - this.dir = dir; - this.setDirection(dir); + this.setDirection(direction); } /** @@ -32,7 +31,7 @@ export class NbLayoutDirectionService { * @returns boolean. * */ public get isLtr(): boolean { - return this.dir === NbLayoutDirection.LTR; + return this.direction === NbLayoutDirection.LTR; } /** @@ -40,7 +39,7 @@ export class NbLayoutDirectionService { * @returns boolean. * */ public get isRtl(): boolean { - return this.dir === NbLayoutDirection.RTL; + return this.direction === NbLayoutDirection.RTL; } /** @@ -48,15 +47,15 @@ export class NbLayoutDirectionService { * @returns NbLayoutDirection. * */ getDirection(): NbLayoutDirection { - return this.dir; + return this.direction; } /** * Sets layout direction. - * @param dir {NbLayoutDirection} direction to set. + * @param direction {NbLayoutDirection} direction to set. * */ - setDirection(dir: NbLayoutDirection) { - this.dir = dir; - this.document.dir = dir; + setDirection(direction: NbLayoutDirection) { + this.direction = direction; + this.document.dir = direction; } } From ba88751e22c47dd9160b1d9015d163dbda8f4591 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 6 Apr 2018 11:16:16 +0300 Subject: [PATCH 37/89] refactor(direction-service): change helpers to be methods --- src/framework/theme/components/badge/badge.component.ts | 2 +- src/framework/theme/services/direction.service.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/framework/theme/components/badge/badge.component.ts b/src/framework/theme/components/badge/badge.component.ts index ffb1e0670b..d7b858d13d 100644 --- a/src/framework/theme/components/badge/badge.component.ts +++ b/src/framework/theme/components/badge/badge.component.ts @@ -98,7 +98,7 @@ export class NbBadgeComponent { return NbBadgeComponent.TOP_RIGHT; } - const { isLtr } = this.layoutDirectionService; + const isLtr = this.layoutDirectionService.isLtr(); const startValue = isLtr ? 'left' : 'right'; const endValue = isLtr ? 'right' : 'left'; return this.position diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index b9bc733fd9..60743e5b6e 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -30,7 +30,7 @@ export class NbLayoutDirectionService { * Returns true if layout direction set to left to right. * @returns boolean. * */ - public get isLtr(): boolean { + public isLtr(): boolean { return this.direction === NbLayoutDirection.LTR; } @@ -38,7 +38,7 @@ export class NbLayoutDirectionService { * Returns true if layout direction set to right to left. * @returns boolean. * */ - public get isRtl(): boolean { + public isRtl(): boolean { return this.direction === NbLayoutDirection.RTL; } From db87aad544849ca498310db474b95a65073f7240 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 6 Apr 2018 15:46:48 +0300 Subject: [PATCH 38/89] feat(rtl): add position helper for popover component --- .../context-menu/context-menu.directive.ts | 6 ++-- .../popover/helpers/placement.helper.ts | 26 ++++++++++++++ .../components/popover/popover.directive.ts | 35 ++++++------------- .../components/popover/popover.module.ts | 3 +- 4 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 src/framework/theme/components/popover/helpers/placement.helper.ts diff --git a/src/framework/theme/components/context-menu/context-menu.directive.ts b/src/framework/theme/components/context-menu/context-menu.directive.ts index fcc91e3381..019e6b8c5f 100644 --- a/src/framework/theme/components/context-menu/context-menu.directive.ts +++ b/src/framework/theme/components/context-menu/context-menu.directive.ts @@ -16,7 +16,7 @@ import { NbContextMenuComponent } from './context-menu.component'; import { NbPositioningHelper } from '../popover/helpers/positioning.helper'; import { NbAdjustmentHelper } from '../popover/helpers/adjustment.helper'; import { NbTriggerHelper } from '../popover/helpers/trigger.helper'; -import { NbLayoutDirectionService } from '../../services/direction.service'; +import { NbPlacementHelper } from '../popover/helpers/placement.helper'; /** * Full featured context menu directive. @@ -99,7 +99,7 @@ export class NbContextMenuDirective implements OnInit, OnDestroy { adjustmentHelper: NbAdjustmentHelper, triggerHelper: NbTriggerHelper, @Inject(PLATFORM_ID) platformId, - directionService: NbLayoutDirectionService) { + placementHelper: NbPlacementHelper) { /** * Initialize popover with all the important inputs. * */ @@ -110,7 +110,7 @@ export class NbContextMenuDirective implements OnInit, OnDestroy { adjustmentHelper, triggerHelper, platformId, - directionService, + placementHelper, ); this.popover.content = NbContextMenuComponent; this.popover.placement = NbPopoverPlacement.BOTTOM; diff --git a/src/framework/theme/components/popover/helpers/placement.helper.ts b/src/framework/theme/components/popover/helpers/placement.helper.ts new file mode 100644 index 0000000000..62c02c5e45 --- /dev/null +++ b/src/framework/theme/components/popover/helpers/placement.helper.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@angular/core'; +import { NbLayoutDirectionService } from '../../../services/direction.service'; +import { NbPopoverPlacement, NbPopoverLogicalPlacement } from './model'; + +@Injectable() +export class NbPlacementHelper { + constructor(private layoutDirectionService: NbLayoutDirectionService) {} + + /* + * Maps logical position to physical according to current layout direction. + * */ + public toPhysicalPlacement( + placement: NbPopoverPlacement | NbPopoverLogicalPlacement, + ): NbPopoverPlacement { + const isLtr = this.layoutDirectionService.isLtr(); + + if (placement === NbPopoverLogicalPlacement.START) { + return isLtr ? NbPopoverPlacement.LEFT : NbPopoverPlacement.RIGHT; + } + if (placement === NbPopoverLogicalPlacement.END) { + return isLtr ? NbPopoverPlacement.RIGHT : NbPopoverPlacement.LEFT; + } + + return placement; + } +} diff --git a/src/framework/theme/components/popover/popover.directive.ts b/src/framework/theme/components/popover/popover.directive.ts index 139f261997..df10da8cff 100644 --- a/src/framework/theme/components/popover/popover.directive.ts +++ b/src/framework/theme/components/popover/popover.directive.ts @@ -14,7 +14,6 @@ import { takeWhile } from 'rxjs/operators/takeWhile'; import { NbPositioningHelper } from './helpers/positioning.helper'; import { NbPopoverComponent, NbPopoverContent } from './popover.component'; import { NbThemeService } from '../../services/theme.service'; -import { NbLayoutDirectionService } from '../../services/direction.service'; import { NbAdjustmentHelper } from './helpers/adjustment.helper'; import { NbTriggerHelper } from './helpers/trigger.helper'; import { @@ -24,6 +23,7 @@ import { NbPopoverPosition, NbPopoverLogicalPlacement, } from './helpers/model'; +import { NbPlacementHelper } from './helpers/placement.helper'; /** * Powerful popover directive, which provides the best UX for your users. @@ -156,7 +156,7 @@ export class NbPopoverDirective implements OnInit, OnDestroy { private adjustmentHelper: NbAdjustmentHelper, private triggerHelper: NbTriggerHelper, @Inject(PLATFORM_ID) private platformId, - private layoutDirectionService: NbLayoutDirectionService, + private placementHelper: NbPlacementHelper, ) {} ngOnInit() { @@ -319,25 +319,7 @@ export class NbPopoverDirective implements OnInit, OnDestroy { return this.calcAdjustment(placed, host); } - return { - position: this.calcPosition(placed, host), - placement: this.physicalPlacement, - }; - } - - /* - * Maps logical position to physical according to current layout direction. - * */ - private get physicalPlacement(): NbPopoverPlacement { - const { isLtr } = this.layoutDirectionService; - if (this.placement === NbPopoverLogicalPlacement.START) { - return isLtr ? NbPopoverPlacement.LEFT : NbPopoverPlacement.RIGHT; - } - if (this.placement === NbPopoverLogicalPlacement.END) { - return isLtr ? NbPopoverPlacement.RIGHT : NbPopoverPlacement.LEFT; - } - - return this.placement; + return this.calcPosition(placed, host); } /* @@ -345,14 +327,19 @@ export class NbPopoverDirective implements OnInit, OnDestroy { * see {@link NbAdjustmentHelper}. * */ private calcAdjustment(placed: ClientRect, host: ClientRect): NbPopoverPosition { - return this.adjustmentHelper.adjust(placed, host, this.physicalPlacement, this.adjustment); + const placement = this.placementHelper.toPhysicalPlacement(this.placement); + return this.adjustmentHelper.adjust(placed, host, placement, this.adjustment); } /* * Calculate position. * see {@link NbPositioningHelper} * */ - private calcPosition(placed: ClientRect, host: ClientRect): {top: number, left: number} { - return this.positioningHelper.calcPosition(placed, host, this.physicalPlacement); + private calcPosition(placed: ClientRect, host: ClientRect): NbPopoverPosition { + const placement = this.placementHelper.toPhysicalPlacement(this.placement); + return { + position: this.positioningHelper.calcPosition(placed, host, placement), + placement, + }; } } diff --git a/src/framework/theme/components/popover/popover.module.ts b/src/framework/theme/components/popover/popover.module.ts index 6bdc2c125e..59d0556a63 100644 --- a/src/framework/theme/components/popover/popover.module.ts +++ b/src/framework/theme/components/popover/popover.module.ts @@ -11,13 +11,14 @@ import { NbPopoverDirective } from './popover.directive'; import { NbAdjustmentHelper } from './helpers/adjustment.helper'; import { NbPositioningHelper } from './helpers/positioning.helper'; import { NbTriggerHelper } from './helpers/trigger.helper'; +import { NbPlacementHelper } from './helpers/placement.helper'; @NgModule({ imports: [NbSharedModule], declarations: [NbPopoverComponent, NbPopoverDirective], exports: [NbPopoverDirective], entryComponents: [NbPopoverComponent], - providers: [NbAdjustmentHelper, NbPositioningHelper, NbTriggerHelper], + providers: [NbAdjustmentHelper, NbPositioningHelper, NbTriggerHelper, NbPlacementHelper], }) export class NbPopoverModule { } From 3d788bb509478a857c03c66baef1dd0214c08424 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 6 Apr 2018 17:56:57 +0300 Subject: [PATCH 39/89] refactorting(sidebar): add physical position properties back --- e2e/sidebar-one.e2e-spec.ts | 6 +-- e2e/sidebar-two.e2e-spec.ts | 6 +-- e2e/sidebar.e2e-spec.ts | 6 +-- .../theme-change-test.component.ts | 2 +- .../theme-dynamic-test.component.ts | 2 +- .../sidebar-test-one.component.ts | 2 +- .../sidebar-test-three.component.ts | 2 +- .../sidebar-test-two.component.ts | 2 +- .../sidebar-test/sidebar-test.component.ts | 14 +++--- .../sidebar/_sidebar.component.theme.scss | 20 +++++++++ .../components/sidebar/sidebar.component.scss | 19 ++++++-- .../components/sidebar/sidebar.component.ts | 45 ++++++++++++++++--- 12 files changed, 95 insertions(+), 31 deletions(-) diff --git a/e2e/sidebar-one.e2e-spec.ts b/e2e/sidebar-one.e2e-spec.ts index 2b3bc89d82..81f779e6db 100644 --- a/e2e/sidebar-one.e2e-spec.ts +++ b/e2e/sidebar-one.e2e-spec.ts @@ -27,14 +27,14 @@ describe('nb-sidebar-one', () => { }); }); - it('should render sidebar default sidebar at start', () => { + it('should render sidebar default sidebar at left', () => { element.all(by.css('nb-sidebar')).get(0).getCssValue('order').then(value => { expect(value).toMatch('0'); }); }); - it('should render end sidebar at end', () => { - element(by.css('nb-sidebar[end]')).getCssValue('order').then(value => { + it('should render right sidebar at right', () => { + element(by.css('nb-sidebar[right]')).getCssValue('order').then(value => { expect(value).toMatch('2'); }); }); diff --git a/e2e/sidebar-two.e2e-spec.ts b/e2e/sidebar-two.e2e-spec.ts index c375aaba75..1b817bf013 100644 --- a/e2e/sidebar-two.e2e-spec.ts +++ b/e2e/sidebar-two.e2e-spec.ts @@ -22,7 +22,7 @@ describe('nb-sidebar-two', () => { // }); // }); - it('should render start non-fixed sidebar height minus header', () => { + it('should render left non-fixed sidebar height minus header', () => { Promise.all([ element(by.css('nb-layout')).getSize(), element(by.css('nb-layout-header')).getSize(), @@ -38,8 +38,8 @@ describe('nb-sidebar-two', () => { }); }); - it('should render fixed end sidebar at end', () => { - element(by.css('nb-sidebar[end]')).getCssValue('right').then(value => { + it('should render fixed right sidebar at right', () => { + element(by.css('nb-sidebar[right]')).getCssValue('right').then(value => { expect(value).toMatch('0'); }); }); diff --git a/e2e/sidebar.e2e-spec.ts b/e2e/sidebar.e2e-spec.ts index 217e8118f5..03a06ade57 100644 --- a/e2e/sidebar.e2e-spec.ts +++ b/e2e/sidebar.e2e-spec.ts @@ -26,7 +26,7 @@ describe('nb-sidebar', () => { it('should open/close sidebar', () => { - const button = element(by.css('#collapse-start')); + const button = element(by.css('#collapse-left')); const sidebar = element(by.css('nb-sidebar[fixed]')); button.click().then(() => { @@ -56,8 +56,8 @@ describe('nb-sidebar', () => { it('should open/compact sidebar', () => { - const button = element(by.css('#collapse-end')); - const sidebar = element(by.css('nb-sidebar[end]')); + const button = element(by.css('#collapse-right')); + const sidebar = element(by.css('nb-sidebar[right]')); button.click().then(() => { return browser.driver.wait(() => { diff --git a/src/app/layout-test/theme-change-test.component.ts b/src/app/layout-test/theme-change-test.component.ts index 9d3ecf8303..d46493d7e5 100644 --- a/src/app/layout-test/theme-change-test.component.ts +++ b/src/app/layout-test/theme-change-test.component.ts @@ -16,7 +16,7 @@ import { NbThemeService } from '@nebular/theme'; - + Sidebar content diff --git a/src/app/layout-test/theme-dynamic-test.component.ts b/src/app/layout-test/theme-dynamic-test.component.ts index 7e1c3cbc85..11119dab83 100644 --- a/src/app/layout-test/theme-dynamic-test.component.ts +++ b/src/app/layout-test/theme-dynamic-test.component.ts @@ -20,7 +20,7 @@ import { NbDynamicToAddComponent } from '../dynamic.component'; - + Sidebar content diff --git a/src/app/sidebar-test/sidebar-test-one.component.ts b/src/app/sidebar-test/sidebar-test-one.component.ts index ea20fa5e0c..d61c08dd56 100644 --- a/src/app/sidebar-test/sidebar-test-one.component.ts +++ b/src/app/sidebar-test/sidebar-test-one.component.ts @@ -21,7 +21,7 @@ import { Component } from '@angular/core'; Left - + Right diff --git a/src/app/sidebar-test/sidebar-test-three.component.ts b/src/app/sidebar-test/sidebar-test-three.component.ts index 9c2e6b5271..54fa40371e 100644 --- a/src/app/sidebar-test/sidebar-test-three.component.ts +++ b/src/app/sidebar-test/sidebar-test-three.component.ts @@ -24,7 +24,7 @@ import { Component } from '@angular/core'; Left - + Right diff --git a/src/app/sidebar-test/sidebar-test-two.component.ts b/src/app/sidebar-test/sidebar-test-two.component.ts index 0a746bfc74..9f0ab15a2e 100644 --- a/src/app/sidebar-test/sidebar-test-two.component.ts +++ b/src/app/sidebar-test/sidebar-test-two.component.ts @@ -24,7 +24,7 @@ import { Component } from '@angular/core'; Left - + Right diff --git a/src/app/sidebar-test/sidebar-test.component.ts b/src/app/sidebar-test/sidebar-test.component.ts index 149b4a8204..9b78404fcf 100644 --- a/src/app/sidebar-test/sidebar-test.component.ts +++ b/src/app/sidebar-test/sidebar-test.component.ts @@ -22,19 +22,19 @@ import { NbSidebarService } from '@nebular/theme'; Akveo - - + + - + - + Some Header {{ content }} - + {{ content }} @@ -58,11 +58,11 @@ export class NbSidebarTestComponent implements OnInit { constructor(private sidebarService: NbSidebarService) { } collapseLeft() { - this.sidebarService.toggle(false, 'start'); + this.sidebarService.toggle(false, 'left'); } collapseRight() { - this.sidebarService.toggle(true, 'end'); + this.sidebarService.toggle(true, 'right'); } ngOnInit() { diff --git a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss index dd9a970d63..bc12fa70d9 100644 --- a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss +++ b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss @@ -115,6 +115,24 @@ } // we need to pull the content + &.left.fixed ~ .content { + margin-left: nb-theme(sidebar-width-compact); + } + + &.fixed.right ~ .content { + margin-left: 0; + margin-right: nb-theme(sidebar-width-compact); + } + + &.left.fixed ~ .content.center { + padding-left: nb-theme(sidebar-width-compact); + } + + &.fixed.right ~ .content.center { + padding-left: 0; + padding-right: nb-theme(sidebar-width-compact); + } + &.start.fixed ~ .content { @include rtl-prop(margin-left, margin-right, nb-theme(sidebar-width-compact), 0); } @@ -132,10 +150,12 @@ } } + &.fixed.left.collapsed + .content, &.fixed.start.collapsed + .content { margin-left: 0; } + &.fixed.right.collapsed + .content, &.fixed.end.collapsed + .content { margin-right: 0; } diff --git a/src/framework/theme/components/sidebar/sidebar.component.scss b/src/framework/theme/components/sidebar/sidebar.component.scss index 9b9e7dccb6..54a1266ebd 100644 --- a/src/framework/theme/components/sidebar/sidebar.component.scss +++ b/src/framework/theme/components/sidebar/sidebar.component.scss @@ -27,6 +27,12 @@ flex-direction: column; } + &.right { + @include rtl(order, 4, 0); + margin-right: 0; + margin-left: auto; + } + &.end { order: 4; @include rtl-prop(margin-right, margin-left, 0, auto); @@ -41,13 +47,20 @@ top: 0; bottom: 0; - @include rtl-prop(left, right, 0, auto); + left: 0; - &.end { - @include rtl-prop(right, left, 0, auto); + &.right { + right: 0; } } + &.fixed.start { + @include rtl-prop(left, right, 0, auto); + } + &.fixed.end { + @include rtl-prop(right, left, 0, auto); + } + /deep/ nb-sidebar-footer { margin-top: auto; display: block; diff --git a/src/framework/theme/components/sidebar/sidebar.component.ts b/src/framework/theme/components/sidebar/sidebar.component.ts index 76743d4c7d..3c2e0c29b2 100644 --- a/src/framework/theme/components/sidebar/sidebar.component.ts +++ b/src/framework/theme/components/sidebar/sidebar.component.ts @@ -47,8 +47,9 @@ export class NbSidebarFooterComponent { /** * Layout sidebar component. * - * Sidebar can be place on the start or the end side of the layout, can be fixed (shown above the content) - * or can push the layout when opened. + * Sidebar can be placed on the left or the right side of the layout, + * or on start or end position of layout (depends on document direction, left to right or right to left) + * It can be fixed (shown above the content) or can push the layout when opened. * * There are three states - `expanded`, `collapsed`, `compacted`. * By default sidebar content is fixed and saves its position while the page is being scrolled. @@ -63,10 +64,10 @@ export class NbSidebarFooterComponent { * * ``` * - * @example Example of fixed sidebar located on the start side, initially collapsed. + * @example Example of fixed sidebar located on the left side, initially collapsed. * * ``` - * + * * Header * * Sidebar content, menu or another component here. @@ -121,7 +122,9 @@ export class NbSidebarComponent implements OnInit, OnDestroy { private alive = true; @HostBinding('class.fixed') fixedValue: boolean = false; - @HostBinding('class.start') startValue: boolean = true; + @HostBinding('class.right') rightValue: boolean = false; + @HostBinding('class.left') leftValue: boolean = true; + @HostBinding('class.start') startValue: boolean = false; @HostBinding('class.end') endValue: boolean = false; // TODO: rename stateValue to state (take a look to the card component) @@ -139,23 +142,51 @@ export class NbSidebarComponent implements OnInit, OnDestroy { } /** - * Places sidebar on the start side + * Places sidebar on the right side + * @type {boolean} + */ + @Input() + set right(val: boolean) { + this.rightValue = convertToBoolProperty(val); + this.leftValue = !this.rightValue; + this.startValue = false; + this.endValue = false; + } + + /** + * Places sidebar on the left side + * @type {boolean} + */ + @Input() + set left(val: boolean) { + this.leftValue = convertToBoolProperty(val); + this.rightValue = !this.leftValue; + this.startValue = false; + this.endValue = false; + } + + /** + * Places sidebar on the start edge of layout * @type {boolean} */ @Input() set start(val: boolean) { this.startValue = convertToBoolProperty(val); this.endValue = !this.startValue; + this.leftValue = false; + this.rightValue = false; } /** - * Places sidebar on the end side + * Places sidebar on the end edge of layout * @type {boolean} */ @Input() set end(val: boolean) { this.endValue = convertToBoolProperty(val); this.startValue = !this.endValue; + this.leftValue = false; + this.rightValue = false; } /** From a147db6d64fcff7581431e15bd91b3e716228d99 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 6 Apr 2018 18:27:26 +0300 Subject: [PATCH 40/89] refactor(layout-column): add physical position properties back --- .../components/layout/layout.component.scss | 18 ++++++++++++++---- .../components/layout/layout.component.ts | 12 ++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/framework/theme/components/layout/layout.component.scss b/src/framework/theme/components/layout/layout.component.scss index 7b2c03c9db..14359a1dc3 100644 --- a/src/framework/theme/components/layout/layout.component.scss +++ b/src/framework/theme/components/layout/layout.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 { -webkit-font-smoothing: antialiased; @@ -37,8 +39,12 @@ flex-direction: row; /deep/ nb-sidebar { - order: 0; - + &.left { + @include rtl(order, 0, 2); + } + &.right { + @include rtl(order, 2, 0); + } &.end { order: 2; } @@ -73,11 +79,15 @@ width: 100%; /deep/ nb-layout-column { - order: 2; + order: 1; flex: 1 0; min-width: 0; // fix for flexbug https://github.com/philipwalton/flexbugs#flexbug-1 + + &.left { + @include rtl(order, 0, 2); + } &.start { - order: 1; + order: 0; } } } diff --git a/src/framework/theme/components/layout/layout.component.ts b/src/framework/theme/components/layout/layout.component.ts index 6d9f9c5d46..59d04f4dc6 100644 --- a/src/framework/theme/components/layout/layout.component.ts +++ b/src/framework/theme/components/layout/layout.component.ts @@ -43,8 +43,19 @@ import { NbWindow, NbDocument } from '../../theme.options'; }) export class NbLayoutColumnComponent { + @HostBinding('class.left') leftValue: boolean; @HostBinding('class.start') startValue: boolean; + /** + * Move the column to the very left position in the layout. + * @param {boolean} val + */ + @Input() + set left(val: boolean) { + this.leftValue = convertToBoolProperty(val); + this.startValue = false; + } + /** * Make columnt first in the layout. * @param {boolean} val @@ -52,6 +63,7 @@ export class NbLayoutColumnComponent { @Input() set start(val: boolean) { this.startValue = convertToBoolProperty(val); + this.leftValue = false; } } From b8999d63715cc05a70f183d176eb8d0356763aa6 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 6 Apr 2018 20:35:50 +0300 Subject: [PATCH 41/89] refactoring(direction-service): set rtl attribute on body Because of bug in angular we can't use multiple :host-context selectors. https://github.com/angular/angular/issues/19199 So we have to combine "dir" attribute with theme name, which set on body. --- .../theme/components/layout/layout.component.ts | 9 +++++++++ .../theme/services/direction.service.ts | 16 +++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/framework/theme/components/layout/layout.component.ts b/src/framework/theme/components/layout/layout.component.ts index 59d04f4dc6..6941e5d92e 100644 --- a/src/framework/theme/components/layout/layout.component.ts +++ b/src/framework/theme/components/layout/layout.component.ts @@ -18,6 +18,7 @@ import { takeWhile } from 'rxjs/operators/takeWhile'; import { convertToBoolProperty } from '../helpers'; import { NbThemeService } from '../../services/theme.service'; import { NbSpinnerService } from '../../services/spinner.service'; +import { NbLayoutDirectionService } from '../../services/direction.service'; import { NbWindow, NbDocument } from '../../theme.options'; /** @@ -308,6 +309,7 @@ export class NbLayoutComponent implements AfterViewInit, OnInit, OnDestroy { protected window: NbWindow, protected document: NbDocument, @Inject(PLATFORM_ID) protected platformId: Object, + protected layoutDirectionService: NbLayoutDirectionService, ) { this.themeService.onThemeChange() @@ -373,6 +375,13 @@ export class NbLayoutComponent implements AfterViewInit, OnInit, OnDestroy { data.listener.next(true); }); + this.layoutDirectionService.onDirectionChange() + .pipe(takeWhile(() => this.alive)) + .subscribe(direction => { + const { body } = this.document; + this.renderer.setAttribute(body, 'dir', direction); + }); + this.afterViewInit$.next(true); } diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index 60743e5b6e..ee6ca3f37d 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -1,5 +1,7 @@ import { InjectionToken, Optional, Inject, Injectable } from '@angular/core'; -import { NbDocument } from '../theme.options'; +import { Observable } from 'rxjs/Observable'; +import { ReplaySubject } from 'rxjs/ReplaySubject'; +import { share } from 'rxjs/operators/share'; /** * Layout direction. @@ -19,8 +21,9 @@ export const NB_LAYOUT_DIRECTION = new InjectionToken('Layout */ @Injectable() export class NbLayoutDirectionService { + private $directionChange = new ReplaySubject(1); + constructor( - private document: NbDocument, @Optional() @Inject(NB_LAYOUT_DIRECTION) private direction = NbLayoutDirection.LTR, ) { this.setDirection(direction); @@ -56,6 +59,13 @@ export class NbLayoutDirectionService { * */ setDirection(direction: NbLayoutDirection) { this.direction = direction; - this.document.dir = direction; + this.$directionChange.next(direction); + } + + /** + * Triggers direction change + */ + onDirectionChange(): Observable { + return this.$directionChange.pipe(share()); } } From d1a709c695b42dea92aecf6dba777498ac695de0 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 6 Apr 2018 20:45:35 +0300 Subject: [PATCH 42/89] feat(rtl): add posibility to prefix :host-context selector Because of bug in angular we can't use multiple :host-context selectors. https://github.com/angular/angular/issues/19199 So we have to combine "dir" attribute with theme name. --- src/framework/theme/styles/_theming.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/styles/_theming.scss b/src/framework/theme/styles/_theming.scss index a6cb732c8e..fc320fa6a9 100644 --- a/src/framework/theme/styles/_theming.scss +++ b/src/framework/theme/styles/_theming.scss @@ -107,12 +107,12 @@ $nb-themes-export: () !global; } // TODO: we hide :host inside of it which is not obvious -@mixin nb-install-component() { +@mixin nb-install-component($selector-prefix: "") { $themes-to-install: get-enabled-themes(); @each $theme-name, $theme in $themes-to-install { - :host-context(.nb-theme-#{$theme-name}) { + :host-context(#{$selector-prefix}.nb-theme-#{$theme-name}) { $theme: set-global-theme-vars($theme, $theme-name); @content; } From 4bb74dd4287f9978ee1fb08db49c95c84951bb19 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 6 Apr 2018 21:05:19 +0300 Subject: [PATCH 43/89] style: use single quotes --- src/framework/theme/styles/_theming.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/theme/styles/_theming.scss b/src/framework/theme/styles/_theming.scss index fc320fa6a9..e3918b229c 100644 --- a/src/framework/theme/styles/_theming.scss +++ b/src/framework/theme/styles/_theming.scss @@ -107,7 +107,7 @@ $nb-themes-export: () !global; } // TODO: we hide :host inside of it which is not obvious -@mixin nb-install-component($selector-prefix: "") { +@mixin nb-install-component($selector-prefix: '') { $themes-to-install: get-enabled-themes(); From bc478ec82a983893e3e5fecf0d5b46d3a7aff00f Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 6 Apr 2018 21:06:17 +0300 Subject: [PATCH 44/89] refactor(rtl): mirror ohrizontl margins for menu icons --- src/framework/theme/styles/themes/_default.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/theme/styles/themes/_default.scss b/src/framework/theme/styles/themes/_default.scss index e0fc71c3c6..36a21257af 100644 --- a/src/framework/theme/styles/themes/_default.scss +++ b/src/framework/theme/styles/themes/_default.scss @@ -184,7 +184,7 @@ $theme: ( menu-item-padding: 0.675rem 1rem 0.75rem, menu-item-separator: separator, menu-icon-font-size: 2.5rem, - menu-icon-margin: 0 0.5rem 0 0, + menu-icon-margin: 0 0.5rem 0, menu-icon-color: color-fg, menu-icon-active-color: color-fg-heading, From daad88e375d7914b66350fbfca7a5da0d6d0d11a Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 9 Apr 2018 12:41:44 +0300 Subject: [PATCH 45/89] fix: resolve merge conflict --- src/framework/theme/components/layout/layout.component.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/src/framework/theme/components/layout/layout.component.scss b/src/framework/theme/components/layout/layout.component.scss index 14359a1dc3..daf68b5286 100644 --- a/src/framework/theme/components/layout/layout.component.scss +++ b/src/framework/theme/components/layout/layout.component.scss @@ -82,7 +82,6 @@ order: 1; flex: 1 0; min-width: 0; // fix for flexbug https://github.com/philipwalton/flexbugs#flexbug-1 - &.left { @include rtl(order, 0, 2); } From 7005da1ec00505ef148a7bda57f6a55a48b1979e Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 9 Apr 2018 12:55:33 +0300 Subject: [PATCH 46/89] fix(layout): update e2e tests to match new flex order --- e2e/layout.e2e-spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/e2e/layout.e2e-spec.ts b/e2e/layout.e2e-spec.ts index c1501b2e54..f0f2ff2163 100644 --- a/e2e/layout.e2e-spec.ts +++ b/e2e/layout.e2e-spec.ts @@ -45,7 +45,7 @@ describe('nb-layout', () => { }); }); - it('should render left with order: 1', () => { + it('should render left with order: 0', () => { element .all( by.css(`#layout-fluid > @@ -54,7 +54,7 @@ describe('nb-layout', () => { .get(0) .getCssValue('order') .then(value => { - expect(value).toMatch('1'); + expect(value).toMatch('0'); }); }); @@ -71,7 +71,7 @@ describe('nb-layout', () => { }); }); - it('should render center with order: 2', () => { + it('should render center with order: 1', () => { element .all( by.css(`#layout-fluid > @@ -80,7 +80,7 @@ describe('nb-layout', () => { .get(1) .getCssValue('order') .then(value => { - expect(value).toMatch('2'); + expect(value).toMatch('1'); }); }); @@ -97,7 +97,7 @@ describe('nb-layout', () => { }); }); - it('should render right with order: 2', () => { + it('should render right with order: 1', () => { element .all( by.css(`#layout-fluid > @@ -106,7 +106,7 @@ describe('nb-layout', () => { .get(2) .getCssValue('order') .then(value => { - expect(value).toMatch('2'); + expect(value).toMatch('1'); }); }); From 5bf7d82809567ec584405b073452dcf567317120 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Wed, 11 Apr 2018 19:34:15 +0300 Subject: [PATCH 47/89] style(badge): remove unsused import --- src/framework/theme/components/badge/badge.component.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/framework/theme/components/badge/badge.component.scss b/src/framework/theme/components/badge/badge.component.scss index c2d51fbd95..3c87d928ed 100644 --- a/src/framework/theme/components/badge/badge.component.scss +++ b/src/framework/theme/components/badge/badge.component.scss @@ -4,8 +4,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -@import '../../styles/core/mixins'; - :host .nb-badge { position: absolute; padding: 0.25em 0.4em; From 33a1ab2189aedf2a15326ef6a05faa745a6ee579 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Wed, 11 Apr 2018 20:32:59 +0300 Subject: [PATCH 48/89] feat(layout): align text right in rtl --- src/framework/theme/components/layout/layout.component.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/framework/theme/components/layout/layout.component.scss b/src/framework/theme/components/layout/layout.component.scss index daf68b5286..4123d29783 100644 --- a/src/framework/theme/components/layout/layout.component.scss +++ b/src/framework/theme/components/layout/layout.component.scss @@ -8,6 +8,8 @@ :host { + @include rtl(text-align, left, right); + -webkit-font-smoothing: antialiased; .layout { From c06f59fc6ae929fc3dc6e3e7b4a492651fa7896a Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 02:21:14 +0300 Subject: [PATCH 49/89] refactor(rtl): add ability to append selector to dir attr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to large amount of bugs with :host/:host-context selectors in angular, we have to add [dir] attribute on body. Since styles from _component.theme.scss, nested in .nb-theme-[theme-name], which also set on body. Therefore triсk with '[dir=rtl] &' will lead to .nb-theme-[theme-name] [dir=rtl], so selector newer work (since theme class and dir attribute are set on the same element). To fix it, we have to combine [dir] with .nb-theme using 'selector-append' function. Then result looks like this. [dir].nb-theme-[theme-name]. But on the other hand, styles from component.scss files scoped to :host, so here we can't append, because then we have to apply dir attribute to every component with rtl styles. So for this files we have to keep next approach: :host { [dir=rtl] & { ... } } and resulting selector will be: [dir=rtl] [host-attr] { ... } --- .../actions/_actions.component.theme.scss | 9 ++-- .../flip-card/_flip-card.component.theme.scss | 2 +- .../checkbox/_checkbox.component.theme.scss | 4 +- .../sidebar/_sidebar.component.theme.scss | 10 ++--- src/framework/theme/styles/core/_mixins.scss | 45 ++++++++++++++----- .../global/bootstrap/_custom-forms.scss | 2 +- 6 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/framework/theme/components/actions/_actions.component.theme.scss b/src/framework/theme/components/actions/_actions.component.theme.scss index e076e2169e..492e8b5905 100644 --- a/src/framework/theme/components/actions/_actions.component.theme.scss +++ b/src/framework/theme/components/actions/_actions.component.theme.scss @@ -20,7 +20,8 @@ border-left, border-right, none!important, - 1px solid nb-theme(actions-separator) + 1px solid nb-theme(actions-separator), + true ); } @@ -39,7 +40,8 @@ border-left, border-right, 1px solid nb-theme(actions-separator), - none + none, + true ); background: transparent; } @@ -54,7 +56,8 @@ border-left, border-right, 1px solid nb-theme(actions-separator), - none + none, + true ); } } diff --git a/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss b/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss index f5ae8ac829..f964e84b9e 100644 --- a/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss +++ b/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss @@ -6,6 +6,6 @@ } .flipcard-body .front-container { - @include rtl-prop(margin-right, margin-left, -100%, auto); + @include rtl-prop(margin-right, margin-left, -100%, auto, true); } } diff --git a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss index 8ef91697be..28679c4018 100644 --- a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss +++ b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss @@ -35,7 +35,7 @@ // locally used mixin @mixin description-style { color: nb-theme(color-fg-heading); - @include rtl-prop(padding-left, padding-right, 0.25rem, 0); + @include rtl-prop(padding-left, padding-right, 0.25rem, 0, true); } @mixin nb-checkbox-theme() { @@ -60,7 +60,7 @@ position: absolute; top: 50%; transform: translateY(-50%); - @include rtl-prop(left, right, 0, auto); + @include rtl-prop(left, right, 0, auto, true); flex: none; display: flex; justify-content: center; diff --git a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss index bc12fa70d9..7beef79483 100644 --- a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss +++ b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss @@ -75,7 +75,7 @@ &::before { position: absolute; content: ''; - @include rtl-prop(left, right, 0, auto); + @include rtl-prop(left, right, 0, auto, true); top: 0; height: 100%; width: 4px; @@ -134,19 +134,19 @@ } &.start.fixed ~ .content { - @include rtl-prop(margin-left, margin-right, nb-theme(sidebar-width-compact), 0); + @include rtl-prop(margin-left, margin-right, nb-theme(sidebar-width-compact), 0, true); } &.fixed.end ~ .content { - @include rtl-prop(margin-right, margin-left, nb-theme(sidebar-width-compact), 0); + @include rtl-prop(margin-right, margin-left, nb-theme(sidebar-width-compact), 0, true); } &.start.fixed ~ .content.center { - @include rtl-prop(padding-left, padding-right, nb-theme(sidebar-width-compact), 0); + @include rtl-prop(padding-left, padding-right, nb-theme(sidebar-width-compact), 0, true); } &.fixed.end ~ .content.center { - @include rtl-prop(padding-right, padding-left, nb-theme(sidebar-width-compact), 0); + @include rtl-prop(padding-right, padding-left, nb-theme(sidebar-width-compact), 0, true); } } diff --git a/src/framework/theme/styles/core/_mixins.scss b/src/framework/theme/styles/core/_mixins.scss index 99ae3a3cd9..4979c2464c 100644 --- a/src/framework/theme/styles/core/_mixins.scss +++ b/src/framework/theme/styles/core/_mixins.scss @@ -194,23 +194,44 @@ } } -@mixin rtl($prop, $ltr-value, $rtl-value) { - #{$prop}: $ltr-value; - [dir=rtl] & { - #{$prop}: $rtl-value; +@mixin rtl-prop($ltr-prop, $rtl-prop, $value, $reset-value: null, $append: false) { + #{$ltr-prop}: $value; + + @if $append == true { + @at-root #{selector-append('[dir=rtl]', &)} { + #{$ltr-prop}: $reset-value; + #{$rtl-prop}: $value; + } + } @else { + [dir=rtl] & { + #{$ltr-prop}: $reset-value; + #{$rtl-prop}: $value; + } } } -@mixin rtl-prop($ltr-prop, $rtl-prop, $value, $reset-value) { - #{$ltr-prop}: $value; - [dir=rtl] & { - #{$ltr-prop}: $reset-value; - #{$rtl-prop}: $value; +@mixin rtl($prop, $ltr-value, $rtl-value, $append: false) { + #{$prop}: $ltr-value; + + @if $append == true { + @at-root #{selector-append('[dir=rtl]', &)} { + #{$prop}: $rtl-value; + } + } @else { + [dir=rtl] & { + #{$prop}: $rtl-value; + } } } -@mixin rtl-only($prop, $value) { - [dir=rtl] & { - #{$prop}: $value; +@mixin rtl-only($prop, $value, $append: false) { + @if $append == true { + @at-root #{selector-append('[dir=rtl]', &)} { + #{$prop}: $value; + } + } @else { + [dir=rtl] & { + #{$prop}: $value; + } } } diff --git a/src/framework/theme/styles/global/bootstrap/_custom-forms.scss b/src/framework/theme/styles/global/bootstrap/_custom-forms.scss index 23c9d131f7..89cf1aaddb 100644 --- a/src/framework/theme/styles/global/bootstrap/_custom-forms.scss +++ b/src/framework/theme/styles/global/bootstrap/_custom-forms.scss @@ -28,7 +28,7 @@ border: nb-theme(checkbox-border-size) solid nb-theme(checkbox-border-color); flex-shrink: 0; position: absolute; - left: 0; + @include rtl-prop(left, right, 0, auto, true); display: flex; justify-content: center; align-items: center; From 634cf91e5e04fcc0045e35b2f8186eba194e54c1 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 02:42:35 +0300 Subject: [PATCH 50/89] feat(rtl): mirror padding on form control description --- src/framework/theme/styles/global/bootstrap/_custom-forms.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/framework/theme/styles/global/bootstrap/_custom-forms.scss b/src/framework/theme/styles/global/bootstrap/_custom-forms.scss index 89cf1aaddb..f737da9cd1 100644 --- a/src/framework/theme/styles/global/bootstrap/_custom-forms.scss +++ b/src/framework/theme/styles/global/bootstrap/_custom-forms.scss @@ -108,6 +108,7 @@ .custom-control-description { padding-left: 0.25rem; + padding-right: 0.25rem; color: nb-theme(color-fg-heading); } } From 25b5ef6ceb178c2f813c0d484f82862eef06829d Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 13:09:02 +0300 Subject: [PATCH 51/89] feat(rtl): context menu add padding mirroring for icons --- .../theme/components/context-menu/context-menu.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/theme/components/context-menu/context-menu.component.scss b/src/framework/theme/components/context-menu/context-menu.component.scss index fae02c85a3..8fe1af38c2 100644 --- a/src/framework/theme/components/context-menu/context-menu.component.scss +++ b/src/framework/theme/components/context-menu/context-menu.component.scss @@ -43,7 +43,7 @@ } .menu-icon:first-child { - padding-left: 1rem; + @include rtl-prop(padding-left, padding-right, 1rem, 3rem); } } } From 8a3253684feccc4d0f8cb37fff64059790dbaaf0 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 13:17:12 +0300 Subject: [PATCH 52/89] feat(rtl): mirror blockquotes --- .../styles/global/typography/_typography.scss | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/styles/global/typography/_typography.scss b/src/framework/theme/styles/global/typography/_typography.scss index bd6257b9b2..bd0147489d 100644 --- a/src/framework/theme/styles/global/typography/_typography.scss +++ b/src/framework/theme/styles/global/typography/_typography.scss @@ -153,13 +153,27 @@ .blockquote { font-size: nb-theme(font-size); - border-left: 0.25rem solid nb-theme(color-fg-highlight); color: nb-theme(color-fg-text); + + @include rtl-prop( + border-left, + border-right, + 0.25rem solid nb-theme(color-fg-highlight), + 0, + true + ); } .blockquote-reverse { font-size: nb-theme(font-size); - border-right: 0.25rem solid nb-theme(color-fg-highlight); color: nb-theme(color-fg-text); + + @include rtl-prop( + border-right, + border-left, + 0.25rem solid nb-theme(color-fg-highlight), + 0, + true + ); } .blockquote-footer { color: nb-theme(color-fg); From 9607103dd7979108cf6069974800a8e989a8ab12 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 13:22:10 +0300 Subject: [PATCH 53/89] feat(rtl): mirror lists padding --- src/framework/theme/styles/global/typography/_typography.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/theme/styles/global/typography/_typography.scss b/src/framework/theme/styles/global/typography/_typography.scss index bd0147489d..800d92438a 100644 --- a/src/framework/theme/styles/global/typography/_typography.scss +++ b/src/framework/theme/styles/global/typography/_typography.scss @@ -210,7 +210,7 @@ } ol,ul { - padding-left: 1.25rem; + @include rtl-prop(padding-left, padding-right, 1.25rem, 0, true); } .alert { From b196c18ab477cdbc3e3d73ede9d5048e02b233cf Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 15:14:27 +0300 Subject: [PATCH 54/89] feat(rtl): move close toast button to the right --- .../theme/styles/global/components/_toaster.theme.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/theme/styles/global/components/_toaster.theme.scss b/src/framework/theme/styles/global/components/_toaster.theme.scss index 421ab2cb5c..c7d2ca3e6c 100644 --- a/src/framework/theme/styles/global/components/_toaster.theme.scss +++ b/src/framework/theme/styles/global/components/_toaster.theme.scss @@ -8,7 +8,7 @@ .toast-close-button { position: absolute; - right: 0.15rem; + @include rtl-prop(right, left, 0.15rem, auto); top: 0.2rem; opacity: 1; background-color: nb-theme(toaster-btn-close-bg); From c0b14a4ab213d4ebd432f23af5a11a455594b4b8 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 15:27:04 +0300 Subject: [PATCH 55/89] feat(rtl): mirror sort icons position in smart table --- .../theme/styles/global/tables/_smart-table.theme.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/styles/global/tables/_smart-table.theme.scss b/src/framework/theme/styles/global/tables/_smart-table.theme.scss index ca0609c763..e5b48722f6 100644 --- a/src/framework/theme/styles/global/tables/_smart-table.theme.scss +++ b/src/framework/theme/styles/global/tables/_smart-table.theme.scss @@ -35,7 +35,8 @@ table tr.ng2-smart-titles { th { padding: nb-theme(smart-table-padding); - padding-right: 1.75rem; + @include ltr-only(padding-right, 1.75rem, true); + @include rtl-only(padding-left, 1.75rem, true); } th a { @@ -52,7 +53,7 @@ border-width: 0.375rem; position: absolute; margin: 0; - right: 0.75rem; + @include rtl-prop(right, left, 0.75rem, auto, true); top: 50%; transform: translate(0, -50%); } From 6be539445ab67751355871ef91d34c664d5801a5 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 15:45:57 +0300 Subject: [PATCH 56/89] feat(rtl): mirror smart table pager styles --- .../global/tables/_smart-table.theme.scss | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/framework/theme/styles/global/tables/_smart-table.theme.scss b/src/framework/theme/styles/global/tables/_smart-table.theme.scss index e5b48722f6..d363f532c0 100644 --- a/src/framework/theme/styles/global/tables/_smart-table.theme.scss +++ b/src/framework/theme/styles/global/tables/_smart-table.theme.scss @@ -166,6 +166,7 @@ .ng2-smart-pagination { display: flex; + padding: 0; .page-item.disabled .page-link, .page-item.disabled .page-link:focus, .page-item.disabled .page-link:hover { background-color: nb-theme(smart-table-paging-hover); @@ -182,7 +183,13 @@ li { &:not(:last-child) { - border-right: 1px solid nb-theme(smart-table-separator); + @include rtl-prop( + border-right, + border-left, + 1px solid nb-theme(smart-table-separator), + none, + true + ); } a.page-link-prev, a.page-link-next { @@ -204,15 +211,39 @@ &:first-child { a, > span { - border-top-left-radius: nb-theme(smart-table-border-radius); - border-bottom-left-radius: nb-theme(smart-table-border-radius); + @include rtl-prop( + border-top-left-radius, + border-top-right-radius, + nb-theme(smart-table-border-radius), + 0, + true + ); + @include rtl-prop( + border-bottom-left-radius, + border-bottom-right-radius, + nb-theme(smart-table-border-radius), + 0, + true + ); } } &:last-child { a, > span { - border-top-right-radius: nb-theme(smart-table-border-radius); - border-bottom-right-radius: nb-theme(smart-table-border-radius); + @include rtl-prop( + border-top-right-radius, + border-top-left-radius, + nb-theme(smart-table-border-radius), + 0, + true + ); + @include rtl-prop( + border-bottom-right-radius, + border-bottom-left-radius, + nb-theme(smart-table-border-radius), + 0, + true + ); } } From 2524167a34780df2bda4a10ca03b9326ba6b3149 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 16:23:33 +0300 Subject: [PATCH 57/89] feat(rtl): mirror buttons with icons styles --- .../theme/styles/global/bootstrap/_icon-buttons.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss b/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss index 6e9ffc3d70..8b7749478b 100644 --- a/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss +++ b/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss @@ -20,11 +20,12 @@ } .btn-with-icon { - text-align: left; - padding-left: 1rem; + @include rtl(text-align, left, right, true); + @include ltr-only(padding-left, 1rem); + @include rtl-only(padding-right, 1rem); .icon { - margin-right: 1rem; + @include rtl-prop(margin-right, margin-left, 1rem, 0, true); } } } From 5f2e323eddace2ff7608e8f5d99058dfca97d35a Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 16:24:38 +0300 Subject: [PATCH 58/89] feat(rtl): mirror form text styles --- src/framework/theme/styles/global/bootstrap/_forms.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/framework/theme/styles/global/bootstrap/_forms.scss b/src/framework/theme/styles/global/bootstrap/_forms.scss index 7ac5168070..13dcc976ae 100644 --- a/src/framework/theme/styles/global/bootstrap/_forms.scss +++ b/src/framework/theme/styles/global/bootstrap/_forms.scss @@ -103,12 +103,13 @@ color: nb-theme(color-fg); font-family: nb-theme(font-main); - &.hint { - margin-left: 1rem; + &.hint, + &.error { + @include ltr-only(margin-left, 1rem); + @include rtl-only(margin-right, 1rem); } &.error { - margin-left: 1rem; color: nb-theme(color-danger); } } From e5696ebee379b890f7a341a204281e0729aa60d3 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 16:27:09 +0300 Subject: [PATCH 59/89] feat(rtl): mirror btn divided group styles --- src/framework/theme/styles/global/bootstrap/_button-group.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/theme/styles/global/bootstrap/_button-group.scss b/src/framework/theme/styles/global/bootstrap/_button-group.scss index e863090396..b20275584d 100644 --- a/src/framework/theme/styles/global/bootstrap/_button-group.scss +++ b/src/framework/theme/styles/global/bootstrap/_button-group.scss @@ -217,7 +217,7 @@ .btn-divided-group { .btn:not(:first-child) { - margin-left: 0.5rem; + @include rtl-prop(margin-left, margin-right, 0.5rem, 0, true); border-radius: nb-theme(btn-border-radius); } From 6b036134c3ae2c8c18282e047ca765563a28c776 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 16:28:07 +0300 Subject: [PATCH 60/89] fix(rtl): add missing ltr only mixin --- src/framework/theme/styles/core/_mixins.scss | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/framework/theme/styles/core/_mixins.scss b/src/framework/theme/styles/core/_mixins.scss index 4979c2464c..0565fa64e6 100644 --- a/src/framework/theme/styles/core/_mixins.scss +++ b/src/framework/theme/styles/core/_mixins.scss @@ -235,3 +235,15 @@ } } } + +@mixin ltr-only($prop, $value, $append: false) { + @if $append == true { + @at-root #{selector-append(':not([dir=rtl])', &)} { + #{$prop}: $value; + } + } @else { + :not([dir=rtl]) & { + #{$prop}: $value; + } + } +} From 8a908b594209e299d0a3a0d280d0e051d27f5035 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 16:34:54 +0300 Subject: [PATCH 61/89] feat(rtl): add dropdown mirrored styles --- .../theme/styles/global/bootstrap/_dropdowns.scss | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/framework/theme/styles/global/bootstrap/_dropdowns.scss b/src/framework/theme/styles/global/bootstrap/_dropdowns.scss index ab9bc74bae..b47fdcd57b 100644 --- a/src/framework/theme/styles/global/bootstrap/_dropdowns.scss +++ b/src/framework/theme/styles/global/bootstrap/_dropdowns.scss @@ -103,7 +103,7 @@ .btn:first-child { width: 90%; - text-align: left; + @include rtl(text-align, left, right, true); } .dropdown-toggle { @@ -126,14 +126,15 @@ .dropdown.btn-group.show, .dropup.btn-group.show { .btn:first-child { - border-bottom-left-radius: 0; + @include ltr-only(border-bottom-left-radius, 0, true); + @include rtl-only(border-bottom-right-radius, 0, true); } } .dropdown, .dropup { .dropdown-toggle { width: 100%; - text-align: left; + @include rtl(text-align, left, right, true); position: relative; } @@ -294,7 +295,7 @@ .dropdown-toggle::after { top: 50%; transform: translate(0, -50%); - right: 0.75rem; + @include rtl-prop(right, left, 0.75rem, auto, true); } } From ff2856b494d5a48f5447808ee9a839289df88e65 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 18:27:02 +0300 Subject: [PATCH 62/89] style(overrides): remove nonexistent in bootstrap class --- .../global/bootstrap/_button-group.scss | 35 +------------------ 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/src/framework/theme/styles/global/bootstrap/_button-group.scss b/src/framework/theme/styles/global/bootstrap/_button-group.scss index b20275584d..d27543b634 100644 --- a/src/framework/theme/styles/global/bootstrap/_button-group.scss +++ b/src/framework/theme/styles/global/bootstrap/_button-group.scss @@ -66,7 +66,7 @@ @mixin nb-b-button-group-theme() { - .btn-group:not(.btn-toggle-group):not(.btn-divided-group) > .btn + .btn { + .btn-group:not(.btn-divided-group) > .btn + .btn { &.btn-primary { @include dropdown-primary-separator(); } @@ -97,7 +97,6 @@ padding: 0 1rem; } - .btn-toggle-group, .btn-divided-group { .btn { background-color: nb-theme(btn-group-bg); @@ -171,38 +170,6 @@ } } - .btn-toggle-group { - .btn { - position: relative; - } - - .btn:first-child { - border-right: none; - } - - .btn:last-child { - border-left: none; - margin-left: 0; - } - - .btn:not(:first-child):not(:last-child) { - border-left: none; - border-right: none; - } - - .btn:not(.active):not(:hover) + .btn:not(.active):not(:hover) { - &::before { - content: ''; - position: absolute; - background-color: nb-theme(btn-group-separator); - width: 1px; - height: 100%; - top: 0; - left: 0; - } - } - } - .btn-outline-toggle-group { .btn { background-color: transparent; From c2885564de7b5c40cba8c41d4198c5c099010c08 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 19:42:11 +0300 Subject: [PATCH 63/89] feat(dropdown): align dropdown menu automatically --- src/framework/theme/styles/global/bootstrap/_dropdowns.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/framework/theme/styles/global/bootstrap/_dropdowns.scss b/src/framework/theme/styles/global/bootstrap/_dropdowns.scss index b47fdcd57b..276ea80aee 100644 --- a/src/framework/theme/styles/global/bootstrap/_dropdowns.scss +++ b/src/framework/theme/styles/global/bootstrap/_dropdowns.scss @@ -303,6 +303,12 @@ .dropdown-toggle { box-shadow: none; } + + .dropdown-menu.show { + // automatically set direction based on layout direction + // have to use important, since ngbDropdownToggle inlines styles to element + left: auto !important; + } } .dropdown.show { From c44455123e27a59e5340e5f5664850eabb1282b3 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 21:04:12 +0300 Subject: [PATCH 64/89] feat(rtl): add input, button groups rtl styles i'm so sorry --- .../global/bootstrap/_button-group.scss | 129 ++++++++++++++++++ .../styles/global/bootstrap/_input-group.scss | 66 ++++++++- 2 files changed, 189 insertions(+), 6 deletions(-) diff --git a/src/framework/theme/styles/global/bootstrap/_button-group.scss b/src/framework/theme/styles/global/bootstrap/_button-group.scss index d27543b634..d18ce4b3a4 100644 --- a/src/framework/theme/styles/global/bootstrap/_button-group.scss +++ b/src/framework/theme/styles/global/bootstrap/_button-group.scss @@ -92,6 +92,135 @@ } } + .btn-group:not(.btn-divided-group) > .btn:not(.dropdown-toggle) { + &:first-child { + @include rtl-prop( + border-top-left-radius, + border-top-right-radius, + nb-theme(btn-border-radius), + 0, + true + ); + @include rtl-prop( + border-bottom-left-radius, + border-bottom-right-radius, + nb-theme(btn-border-radius), + 0, + true + ); + } + &:last-child { + @include rtl-prop( + border-top-right-radius, + border-top-left-radius, + nb-theme(btn-border-radius), + 0, + true + ); + @include rtl-prop( + border-bottom-right-radius, + border-bottom-left-radius, + nb-theme(btn-border-radius), + 0, + true + ); + } + } + + .btn-group.dropdown { + & > .btn:first-of-type.dropdown-toggle { + @include rtl-prop( + border-top-left-radius, + border-top-right-radius, + nb-theme(btn-border-radius), + 0, + true + ); + } + & > .btn:last-of-type.dropdown-toggle { + @include rtl-prop( + border-top-right-radius, + border-top-left-radius, + nb-theme(btn-border-radius), + 0, + true + ); + } + + &:not(.show) { + & > .btn:first-of-type.dropdown-toggle { + @include rtl-prop( + border-bottom-left-radius, + border-bottom-right-radius, + nb-theme(btn-border-radius), + 0, + true + ); + } + & > .btn:last-of-type.dropdown-toggle { + @include rtl-prop( + border-bottom-right-radius, + border-bottom-left-radius, + nb-theme(btn-border-radius), + 0, + true + ); + } + } + + &.show > .btn.dropdown-toggle { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + } + + .btn-group.dropup { + & > .btn:first-of-type.dropdown-toggle { + @include rtl-prop( + border-bottom-left-radius, + border-bottom-right-radius, + nb-theme(btn-border-radius), + 0, + true + ); + } + & > .btn:last-of-type.dropdown-toggle { + @include rtl-prop( + border-bottom-right-radius, + border-bottom-left-radius, + nb-theme(btn-border-radius), + 0, + true + ); + } + + &:not(.show) { + & > .btn:first-of-type.dropdown-toggle { + @include rtl-prop( + border-top-left-radius, + border-top-right-radius, + nb-theme(btn-border-radius), + 0, + true + ); + } + & > .btn:last-of-type.dropdown-toggle { + @include rtl-prop( + border-top-right-radius, + border-top-left-radius, + nb-theme(btn-border-radius), + 0, + true + ); + } + } + + &.show > .btn.dropdown-toggle { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + } + .btn-group-icon { font-size: 1.5rem; padding: 0 1rem; diff --git a/src/framework/theme/styles/global/bootstrap/_input-group.scss b/src/framework/theme/styles/global/bootstrap/_input-group.scss index 9ace87652f..772b2222d2 100644 --- a/src/framework/theme/styles/global/bootstrap/_input-group.scss +++ b/src/framework/theme/styles/global/bootstrap/_input-group.scss @@ -4,16 +4,22 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ +@import '../../core/mixins'; + @mixin nb-b-input-group-theme() { + $border-width: nb-theme(form-control-border-width); + $border-type: nb-theme(form-control-border-type); + $border-color: nb-theme(form-control-border-color); + $form-control-border: $border-width $border-type $border-color; + .input-group-addon, .input-group-icon { font-size: 1.5rem; padding: 0.25rem 1rem; - border-right: none; - border-top-right-radius: 0; - border-bottom-right-radius: 0; color: nb-theme(form-control-placeholder-color); + + @include rtl-prop(border-right, border-left, none, $form-control-border, true); } .input-group-addon { @@ -42,9 +48,57 @@ } } - .input-group-icon + .form-control { - border-left: none; - padding-left: 0; + .input-group { + .form-control:first-child, + .input-group-addon:first-child, + .input-group-prepend .btn:first-child, + .input-group-btn .btn:first-child { + @include rtl-prop( + border-top-right-radius, + border-top-left-radius, + 0, + nb-theme(form-control-border-radius), + true + ); + + @include rtl-prop( + border-bottom-right-radius, + border-bottom-left-radius, + 0, + nb-theme(form-control-border-radius), + true + ); + } + .form-control:last-child, + .input-group-addon:last-child, + .input-group-append .btn:last-child, + .input-group-btn .btn:last-child { + @include rtl-prop( + border-top-left-radius, + border-top-right-radius, + 0, + nb-theme(form-control-border-radius), + true + ); + + @include rtl-prop( + border-bottom-left-radius, + border-bottom-right-radius, + 0, + nb-theme(form-control-border-radius), + true + ); + } + + .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; + } } .input-group-sm > .form-control { From 15d0ff28ff0bb015b01c5063f9c3afc655fac63c Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Thu, 12 Apr 2018 21:58:53 +0300 Subject: [PATCH 65/89] feat(rtl): add rtl toggle component into test app --- src/app/app.component.ts | 5 +++- src/app/app.module.ts | 2 ++ .../layout-direction-toggle.component.scss | 12 +++++++++ .../layout-direction-toggle.component.ts | 27 +++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/app/layout-direction-toggle/layout-direction-toggle.component.scss create mode 100644 src/app/layout-direction-toggle/layout-direction-toggle.component.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 5440583769..787bf0e9c1 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -10,7 +10,10 @@ import 'style-loader!./app.themes.scss'; @Component({ selector: 'nb-app-root', - template: ``, + template: ` + + + `, }) export class NbAppComponent { } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 7f460e0fbf..f6e19f68d6 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -84,6 +84,7 @@ import { AuthGuard } from './auth-guard.service'; import { RoleProvider } from './role.provider'; import { NbDynamicToAddComponent } from './dynamic.component'; import { NbPlaygroundModule } from '../playground/playground.module'; +import { NbLayoutDirectionToggleComponent } from './layout-direction-toggle/layout-direction-toggle.component'; const NB_TEST_COMPONENTS = [ NbAppComponent, @@ -226,6 +227,7 @@ const NB_TEST_COMPONENTS = [ ], declarations: [ ...NB_TEST_COMPONENTS, + NbLayoutDirectionToggleComponent, ], entryComponents: [ NbDynamicToAddComponent, diff --git a/src/app/layout-direction-toggle/layout-direction-toggle.component.scss b/src/app/layout-direction-toggle/layout-direction-toggle.component.scss new file mode 100644 index 0000000000..935f037357 --- /dev/null +++ b/src/app/layout-direction-toggle/layout-direction-toggle.component.scss @@ -0,0 +1,12 @@ +:host { + display: block; + padding: 0.5em; + + label { + margin: 0; + } + + span { + vertical-align: middle; + } +} diff --git a/src/app/layout-direction-toggle/layout-direction-toggle.component.ts b/src/app/layout-direction-toggle/layout-direction-toggle.component.ts new file mode 100644 index 0000000000..35442c051c --- /dev/null +++ b/src/app/layout-direction-toggle/layout-direction-toggle.component.ts @@ -0,0 +1,27 @@ +import { Component } from '@angular/core'; +import { NbLayoutDirectionService, NbLayoutDirection } from '@nebular/theme'; + +@Component({ + selector: 'nb-layout-direction-toggle', + styleUrls: [ './layout-direction-toggle.component.scss' ], + template: ` + + `, +}) +export class NbLayoutDirectionToggleComponent { + constructor(private directionService: NbLayoutDirectionService) {} + + get isRtl() { + return this.directionService.isRtl(); + } + + toggleFlow() { + const oppositeDirection = this.isRtl + ? NbLayoutDirection.LTR + : NbLayoutDirection.RTL; + this.directionService.setDirection(oppositeDirection); + } +} From 5ea5863e00e7ce373fd623cd9119e59431c5e772 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 13 Apr 2018 10:36:35 +0300 Subject: [PATCH 66/89] refactor(rtl-mixins): remove append flag Make mixins work in both .component.scss, _theme.scss files w/o 'append' flag. Apply '[dir=rtl]selector' and '[dir=rtl] selector' selectors simultaneously. --- .../actions/_actions.component.theme.scss | 9 +-- .../flip-card/_flip-card.component.theme.scss | 2 +- .../checkbox/_checkbox.component.theme.scss | 4 +- .../sidebar/_sidebar.component.theme.scss | 10 ++-- src/framework/theme/styles/core/_mixins.scss | 55 ++++++------------- .../global/bootstrap/_button-group.scss | 38 +++++-------- .../global/bootstrap/_custom-forms.scss | 2 +- .../styles/global/bootstrap/_dropdowns.scss | 10 ++-- .../global/bootstrap/_icon-buttons.scss | 4 +- .../styles/global/bootstrap/_input-group.scss | 14 ++--- .../global/tables/_smart-table.theme.scss | 21 +++---- .../styles/global/typography/_typography.scss | 8 +-- 12 files changed, 65 insertions(+), 112 deletions(-) diff --git a/src/framework/theme/components/actions/_actions.component.theme.scss b/src/framework/theme/components/actions/_actions.component.theme.scss index 492e8b5905..e076e2169e 100644 --- a/src/framework/theme/components/actions/_actions.component.theme.scss +++ b/src/framework/theme/components/actions/_actions.component.theme.scss @@ -20,8 +20,7 @@ border-left, border-right, none!important, - 1px solid nb-theme(actions-separator), - true + 1px solid nb-theme(actions-separator) ); } @@ -40,8 +39,7 @@ border-left, border-right, 1px solid nb-theme(actions-separator), - none, - true + none ); background: transparent; } @@ -56,8 +54,7 @@ border-left, border-right, 1px solid nb-theme(actions-separator), - none, - true + none ); } } diff --git a/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss b/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss index f964e84b9e..f5ae8ac829 100644 --- a/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss +++ b/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss @@ -6,6 +6,6 @@ } .flipcard-body .front-container { - @include rtl-prop(margin-right, margin-left, -100%, auto, true); + @include rtl-prop(margin-right, margin-left, -100%, auto); } } diff --git a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss index 28679c4018..8ef91697be 100644 --- a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss +++ b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss @@ -35,7 +35,7 @@ // locally used mixin @mixin description-style { color: nb-theme(color-fg-heading); - @include rtl-prop(padding-left, padding-right, 0.25rem, 0, true); + @include rtl-prop(padding-left, padding-right, 0.25rem, 0); } @mixin nb-checkbox-theme() { @@ -60,7 +60,7 @@ position: absolute; top: 50%; transform: translateY(-50%); - @include rtl-prop(left, right, 0, auto, true); + @include rtl-prop(left, right, 0, auto); flex: none; display: flex; justify-content: center; diff --git a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss index 7beef79483..bc12fa70d9 100644 --- a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss +++ b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss @@ -75,7 +75,7 @@ &::before { position: absolute; content: ''; - @include rtl-prop(left, right, 0, auto, true); + @include rtl-prop(left, right, 0, auto); top: 0; height: 100%; width: 4px; @@ -134,19 +134,19 @@ } &.start.fixed ~ .content { - @include rtl-prop(margin-left, margin-right, nb-theme(sidebar-width-compact), 0, true); + @include rtl-prop(margin-left, margin-right, nb-theme(sidebar-width-compact), 0); } &.fixed.end ~ .content { - @include rtl-prop(margin-right, margin-left, nb-theme(sidebar-width-compact), 0, true); + @include rtl-prop(margin-right, margin-left, nb-theme(sidebar-width-compact), 0); } &.start.fixed ~ .content.center { - @include rtl-prop(padding-left, padding-right, nb-theme(sidebar-width-compact), 0, true); + @include rtl-prop(padding-left, padding-right, nb-theme(sidebar-width-compact), 0); } &.fixed.end ~ .content.center { - @include rtl-prop(padding-right, padding-left, nb-theme(sidebar-width-compact), 0, true); + @include rtl-prop(padding-right, padding-left, nb-theme(sidebar-width-compact), 0); } } diff --git a/src/framework/theme/styles/core/_mixins.scss b/src/framework/theme/styles/core/_mixins.scss index 0565fa64e6..d89333e7d1 100644 --- a/src/framework/theme/styles/core/_mixins.scss +++ b/src/framework/theme/styles/core/_mixins.scss @@ -194,56 +194,35 @@ } } -@mixin rtl-prop($ltr-prop, $rtl-prop, $value, $reset-value: null, $append: false) { +@mixin rtl-prop($ltr-prop, $rtl-prop, $value, $reset-value: null) { #{$ltr-prop}: $value; - @if $append == true { - @at-root #{selector-append('[dir=rtl]', &)} { - #{$ltr-prop}: $reset-value; - #{$rtl-prop}: $value; - } - } @else { - [dir=rtl] & { - #{$ltr-prop}: $reset-value; - #{$rtl-prop}: $value; - } + @at-root #{selector-append('[dir=rtl]', &)}, + [dir=rtl] & { + #{$ltr-prop}: $reset-value; + #{$rtl-prop}: $value; } } -@mixin rtl($prop, $ltr-value, $rtl-value, $append: false) { +@mixin rtl($prop, $ltr-value, $rtl-value) { #{$prop}: $ltr-value; - @if $append == true { - @at-root #{selector-append('[dir=rtl]', &)} { - #{$prop}: $rtl-value; - } - } @else { - [dir=rtl] & { - #{$prop}: $rtl-value; - } + @at-root #{selector-append('[dir=rtl]', &)}, + [dir=rtl] & { + #{$prop}: $rtl-value; } } -@mixin rtl-only($prop, $value, $append: false) { - @if $append == true { - @at-root #{selector-append('[dir=rtl]', &)} { - #{$prop}: $value; - } - } @else { - [dir=rtl] & { - #{$prop}: $value; - } +@mixin rtl-only($prop, $value) { + @at-root #{selector-append('[dir=rtl]', &)}, + [dir=rtl] & { + #{$prop}: $value; } } -@mixin ltr-only($prop, $value, $append: false) { - @if $append == true { - @at-root #{selector-append(':not([dir=rtl])', &)} { - #{$prop}: $value; - } - } @else { - :not([dir=rtl]) & { - #{$prop}: $value; - } +@mixin ltr-only($prop, $value) { + @at-root #{selector-append(':not([dir=rtl])', &)}, + :not([dir=rtl]) & { + #{$prop}: $value; } } diff --git a/src/framework/theme/styles/global/bootstrap/_button-group.scss b/src/framework/theme/styles/global/bootstrap/_button-group.scss index d18ce4b3a4..4d67a3146d 100644 --- a/src/framework/theme/styles/global/bootstrap/_button-group.scss +++ b/src/framework/theme/styles/global/bootstrap/_button-group.scss @@ -98,15 +98,13 @@ border-top-left-radius, border-top-right-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); @include rtl-prop( border-bottom-left-radius, border-bottom-right-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); } &:last-child { @@ -114,15 +112,13 @@ border-top-right-radius, border-top-left-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); @include rtl-prop( border-bottom-right-radius, border-bottom-left-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); } } @@ -133,8 +129,7 @@ border-top-left-radius, border-top-right-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); } & > .btn:last-of-type.dropdown-toggle { @@ -142,8 +137,7 @@ border-top-right-radius, border-top-left-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); } @@ -153,8 +147,7 @@ border-bottom-left-radius, border-bottom-right-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); } & > .btn:last-of-type.dropdown-toggle { @@ -162,8 +155,7 @@ border-bottom-right-radius, border-bottom-left-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); } } @@ -180,8 +172,7 @@ border-bottom-left-radius, border-bottom-right-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); } & > .btn:last-of-type.dropdown-toggle { @@ -189,8 +180,7 @@ border-bottom-right-radius, border-bottom-left-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); } @@ -200,8 +190,7 @@ border-top-left-radius, border-top-right-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); } & > .btn:last-of-type.dropdown-toggle { @@ -209,8 +198,7 @@ border-top-right-radius, border-top-left-radius, nb-theme(btn-border-radius), - 0, - true + 0 ); } } @@ -313,7 +301,7 @@ .btn-divided-group { .btn:not(:first-child) { - @include rtl-prop(margin-left, margin-right, 0.5rem, 0, true); + @include rtl-prop(margin-left, margin-right, 0.5rem, 0); border-radius: nb-theme(btn-border-radius); } diff --git a/src/framework/theme/styles/global/bootstrap/_custom-forms.scss b/src/framework/theme/styles/global/bootstrap/_custom-forms.scss index f737da9cd1..d2003fb065 100644 --- a/src/framework/theme/styles/global/bootstrap/_custom-forms.scss +++ b/src/framework/theme/styles/global/bootstrap/_custom-forms.scss @@ -28,7 +28,7 @@ border: nb-theme(checkbox-border-size) solid nb-theme(checkbox-border-color); flex-shrink: 0; position: absolute; - @include rtl-prop(left, right, 0, auto, true); + @include rtl-prop(left, right, 0, auto); display: flex; justify-content: center; align-items: center; diff --git a/src/framework/theme/styles/global/bootstrap/_dropdowns.scss b/src/framework/theme/styles/global/bootstrap/_dropdowns.scss index 276ea80aee..5db663e660 100644 --- a/src/framework/theme/styles/global/bootstrap/_dropdowns.scss +++ b/src/framework/theme/styles/global/bootstrap/_dropdowns.scss @@ -103,7 +103,7 @@ .btn:first-child { width: 90%; - @include rtl(text-align, left, right, true); + @include rtl(text-align, left, right); } .dropdown-toggle { @@ -126,15 +126,15 @@ .dropdown.btn-group.show, .dropup.btn-group.show { .btn:first-child { - @include ltr-only(border-bottom-left-radius, 0, true); - @include rtl-only(border-bottom-right-radius, 0, true); + @include ltr-only(border-bottom-left-radius, 0); + @include rtl-only(border-bottom-right-radius, 0); } } .dropdown, .dropup { .dropdown-toggle { width: 100%; - @include rtl(text-align, left, right, true); + @include rtl(text-align, left, right); position: relative; } @@ -295,7 +295,7 @@ .dropdown-toggle::after { top: 50%; transform: translate(0, -50%); - @include rtl-prop(right, left, 0.75rem, auto, true); + @include rtl-prop(right, left, 0.75rem, auto); } } diff --git a/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss b/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss index 8b7749478b..9f1bf91cd5 100644 --- a/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss +++ b/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss @@ -20,12 +20,12 @@ } .btn-with-icon { - @include rtl(text-align, left, right, true); + @include rtl(text-align, left, right); @include ltr-only(padding-left, 1rem); @include rtl-only(padding-right, 1rem); .icon { - @include rtl-prop(margin-right, margin-left, 1rem, 0, true); + @include rtl-prop(margin-right, margin-left, 1rem, 0); } } } diff --git a/src/framework/theme/styles/global/bootstrap/_input-group.scss b/src/framework/theme/styles/global/bootstrap/_input-group.scss index 772b2222d2..3e2ccabe83 100644 --- a/src/framework/theme/styles/global/bootstrap/_input-group.scss +++ b/src/framework/theme/styles/global/bootstrap/_input-group.scss @@ -19,7 +19,7 @@ padding: 0.25rem 1rem; color: nb-theme(form-control-placeholder-color); - @include rtl-prop(border-right, border-left, none, $form-control-border, true); + @include rtl-prop(border-right, border-left, none, $form-control-border); } .input-group-addon { @@ -57,16 +57,14 @@ border-top-right-radius, border-top-left-radius, 0, - nb-theme(form-control-border-radius), - true + nb-theme(form-control-border-radius) ); @include rtl-prop( border-bottom-right-radius, border-bottom-left-radius, 0, - nb-theme(form-control-border-radius), - true + nb-theme(form-control-border-radius) ); } .form-control:last-child, @@ -77,16 +75,14 @@ border-top-left-radius, border-top-right-radius, 0, - nb-theme(form-control-border-radius), - true + nb-theme(form-control-border-radius) ); @include rtl-prop( border-bottom-left-radius, border-bottom-right-radius, 0, - nb-theme(form-control-border-radius), - true + nb-theme(form-control-border-radius) ); } diff --git a/src/framework/theme/styles/global/tables/_smart-table.theme.scss b/src/framework/theme/styles/global/tables/_smart-table.theme.scss index d363f532c0..ba1de57f4d 100644 --- a/src/framework/theme/styles/global/tables/_smart-table.theme.scss +++ b/src/framework/theme/styles/global/tables/_smart-table.theme.scss @@ -35,8 +35,8 @@ table tr.ng2-smart-titles { th { padding: nb-theme(smart-table-padding); - @include ltr-only(padding-right, 1.75rem, true); - @include rtl-only(padding-left, 1.75rem, true); + @include ltr-only(padding-right, 1.75rem); + @include rtl-only(padding-left, 1.75rem); } th a { @@ -53,7 +53,7 @@ border-width: 0.375rem; position: absolute; margin: 0; - @include rtl-prop(right, left, 0.75rem, auto, true); + @include rtl-prop(right, left, 0.75rem, auto); top: 50%; transform: translate(0, -50%); } @@ -187,8 +187,7 @@ border-right, border-left, 1px solid nb-theme(smart-table-separator), - none, - true + none ); } @@ -215,15 +214,13 @@ border-top-left-radius, border-top-right-radius, nb-theme(smart-table-border-radius), - 0, - true + 0 ); @include rtl-prop( border-bottom-left-radius, border-bottom-right-radius, nb-theme(smart-table-border-radius), - 0, - true + 0 ); } } @@ -234,15 +231,13 @@ border-top-right-radius, border-top-left-radius, nb-theme(smart-table-border-radius), - 0, - true + 0 ); @include rtl-prop( border-bottom-right-radius, border-bottom-left-radius, nb-theme(smart-table-border-radius), - 0, - true + 0 ); } } diff --git a/src/framework/theme/styles/global/typography/_typography.scss b/src/framework/theme/styles/global/typography/_typography.scss index 800d92438a..f76ab77886 100644 --- a/src/framework/theme/styles/global/typography/_typography.scss +++ b/src/framework/theme/styles/global/typography/_typography.scss @@ -159,8 +159,7 @@ border-left, border-right, 0.25rem solid nb-theme(color-fg-highlight), - 0, - true + 0 ); } .blockquote-reverse { @@ -171,8 +170,7 @@ border-right, border-left, 0.25rem solid nb-theme(color-fg-highlight), - 0, - true + 0 ); } .blockquote-footer { @@ -210,7 +208,7 @@ } ol,ul { - @include rtl-prop(padding-left, padding-right, 1.25rem, 0, true); + @include rtl-prop(padding-left, padding-right, 1.25rem, 0); } .alert { From 9739bb475066bb4cbbb984a1070336752f24834a Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 13 Apr 2018 10:49:55 +0300 Subject: [PATCH 67/89] feat(rtl): reverse header elements in rtl --- src/framework/theme/styles/global/bootstrap/_modals.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/framework/theme/styles/global/bootstrap/_modals.scss b/src/framework/theme/styles/global/bootstrap/_modals.scss index e78da71e6c..73e4aec728 100644 --- a/src/framework/theme/styles/global/bootstrap/_modals.scss +++ b/src/framework/theme/styles/global/bootstrap/_modals.scss @@ -32,6 +32,8 @@ @include nb-headings(); + @include rtl-only(flex-flow, row-reverse); + .close { text-shadow: none; color: nb-theme(modal-fg-heading); From da7040caff499252ec09d7f6a5e8056a90dcd8ff Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 13 Apr 2018 11:04:40 +0300 Subject: [PATCH 68/89] feat(rtl): mirror controls on toasts --- .../theme/styles/global/components/_toaster.theme.scss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/framework/theme/styles/global/components/_toaster.theme.scss b/src/framework/theme/styles/global/components/_toaster.theme.scss index c7d2ca3e6c..af63ee972d 100644 --- a/src/framework/theme/styles/global/components/_toaster.theme.scss +++ b/src/framework/theme/styles/global/components/_toaster.theme.scss @@ -35,6 +35,16 @@ opacity: 1 !important; } } + // have to use id selector for specifity + /* stylelint-disable-next-line selector-max-id */ + #toast-container > div.toast { + @include rtl-only(padding-left, 15px); + @include rtl-only(padding-right, 50px); + } + .toaster-icon { + @include rtl-only(right, 0); + @include rtl-only(background-position-x, 0); + } .toast-success { background-color: nb-theme(toaster-success); color: nb-theme(toaster-fg) !important; From 4cada3f79cd336118720c9621ab9751ce2106689 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 13 Apr 2018 11:29:03 +0300 Subject: [PATCH 69/89] fix(rtl): keep border radius on single inputs --- src/framework/theme/styles/global/bootstrap/_input-group.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/styles/global/bootstrap/_input-group.scss b/src/framework/theme/styles/global/bootstrap/_input-group.scss index 3e2ccabe83..301168e778 100644 --- a/src/framework/theme/styles/global/bootstrap/_input-group.scss +++ b/src/framework/theme/styles/global/bootstrap/_input-group.scss @@ -49,7 +49,7 @@ } .input-group { - .form-control:first-child, + .form-control:first-child:not(:only-child), .input-group-addon:first-child, .input-group-prepend .btn:first-child, .input-group-btn .btn:first-child { @@ -67,7 +67,7 @@ nb-theme(form-control-border-radius) ); } - .form-control:last-child, + .form-control:last-child:not(:only-child), .input-group-addon:last-child, .input-group-append .btn:last-child, .input-group-btn .btn:last-child { From ad98a2d8cff94ec8d9852e75de14ed76391bcc7e Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 13 Apr 2018 12:12:38 +0300 Subject: [PATCH 70/89] style: update layout direction service description --- src/framework/theme/services/direction.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index ee6ca3f37d..ca06829340 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -17,7 +17,8 @@ export enum NbLayoutDirection { export const NB_LAYOUT_DIRECTION = new InjectionToken('Layout direction'); /** - * Layout Direction Service. Allows you to listen to menu events, or to interact with a menu. + * Layout Direction Service. + * Allows to set or get layout direction and listen to it's changes */ @Injectable() export class NbLayoutDirectionService { From 5ad47ec2f6476844699fdc18418ab5a4baf03d1e Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 13 Apr 2018 12:21:51 +0300 Subject: [PATCH 71/89] feat(rtl): mirror horizontal and vertical menu items padding --- src/framework/theme/styles/themes/_cosmic.scss | 2 +- src/framework/theme/styles/themes/_default.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/styles/themes/_cosmic.scss b/src/framework/theme/styles/themes/_cosmic.scss index 786d0432c2..f7cbf92f04 100644 --- a/src/framework/theme/styles/themes/_cosmic.scss +++ b/src/framework/theme/styles/themes/_cosmic.scss @@ -84,7 +84,7 @@ $theme: ( menu-submenu-active-bg: rgba(0, 255, 170, 0.25), menu-submenu-active-border-color: color-fg-highlight, menu-submenu-active-shadow: 0 2px 12px 0 rgba(0, 255, 170, 0.25), - menu-item-padding: 0.25rem 1rem 0.75rem, + menu-item-padding: 0.25rem 1rem, menu-item-separator: transparent, btn-hero-shadow: 0 4px 10px 0 rgba(33, 7, 77, 0.5), diff --git a/src/framework/theme/styles/themes/_default.scss b/src/framework/theme/styles/themes/_default.scss index 36a21257af..34548f2bc5 100644 --- a/src/framework/theme/styles/themes/_default.scss +++ b/src/framework/theme/styles/themes/_default.scss @@ -181,7 +181,7 @@ $theme: ( menu-group-font-size: 0.875rem, menu-group-fg: color-fg, menu-group-padding: 1rem 1.25rem, - menu-item-padding: 0.675rem 1rem 0.75rem, + menu-item-padding: 0.675rem 1rem, menu-item-separator: separator, menu-icon-font-size: 2.5rem, menu-icon-margin: 0 0.5rem 0, From 7095eed4b8b1b1e257b43c71e4bd6bbadf1fe4c7 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 13 Apr 2018 12:41:14 +0300 Subject: [PATCH 72/89] refactor(rtl): decrease menu item padding --- src/framework/theme/styles/themes/_cosmic.scss | 2 +- src/framework/theme/styles/themes/_default.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/theme/styles/themes/_cosmic.scss b/src/framework/theme/styles/themes/_cosmic.scss index f7cbf92f04..fb952f329f 100644 --- a/src/framework/theme/styles/themes/_cosmic.scss +++ b/src/framework/theme/styles/themes/_cosmic.scss @@ -84,7 +84,7 @@ $theme: ( menu-submenu-active-bg: rgba(0, 255, 170, 0.25), menu-submenu-active-border-color: color-fg-highlight, menu-submenu-active-shadow: 0 2px 12px 0 rgba(0, 255, 170, 0.25), - menu-item-padding: 0.25rem 1rem, + menu-item-padding: 0.25rem 0.75rem, menu-item-separator: transparent, btn-hero-shadow: 0 4px 10px 0 rgba(33, 7, 77, 0.5), diff --git a/src/framework/theme/styles/themes/_default.scss b/src/framework/theme/styles/themes/_default.scss index 34548f2bc5..3ed446f2e9 100644 --- a/src/framework/theme/styles/themes/_default.scss +++ b/src/framework/theme/styles/themes/_default.scss @@ -181,7 +181,7 @@ $theme: ( menu-group-font-size: 0.875rem, menu-group-fg: color-fg, menu-group-padding: 1rem 1.25rem, - menu-item-padding: 0.675rem 1rem, + menu-item-padding: 0.675rem 0.75rem, menu-item-separator: separator, menu-icon-font-size: 2.5rem, menu-icon-margin: 0 0.5rem 0, From 9151f9a6f8f5365dd9fa8965c48a08a3e638a93f Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 13 Apr 2018 12:48:12 +0300 Subject: [PATCH 73/89] feat(rtl): decrease menu item margin --- src/framework/theme/styles/themes/_default.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/theme/styles/themes/_default.scss b/src/framework/theme/styles/themes/_default.scss index 3ed446f2e9..618ae9c996 100644 --- a/src/framework/theme/styles/themes/_default.scss +++ b/src/framework/theme/styles/themes/_default.scss @@ -184,7 +184,7 @@ $theme: ( menu-item-padding: 0.675rem 0.75rem, menu-item-separator: separator, menu-icon-font-size: 2.5rem, - menu-icon-margin: 0 0.5rem 0, + menu-icon-margin: 0 0.25rem 0, menu-icon-color: color-fg, menu-icon-active-color: color-fg-heading, From 789449ade76d70a8d1cd7608641e472df3e1b962 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 20 Apr 2018 15:03:21 +0300 Subject: [PATCH 74/89] refactor(rtl-mixins): simplify rtl mixins --- .../actions/_actions.component.theme.scss | 25 ++-- .../flip-card/_flip-card.component.theme.scss | 3 +- .../checkbox/_checkbox.component.theme.scss | 6 +- .../context-menu/context-menu.component.scss | 8 +- .../components/layout/layout.component.scss | 12 +- .../theme/components/menu/menu.component.scss | 2 +- .../search.component.column-curtain.scss | 3 +- .../styles/search.component.curtain.scss | 3 +- .../search.component.layout-rotate.scss | 3 +- .../styles/search.component.modal-drop.scss | 3 +- .../styles/search.component.modal-half.scss | 3 +- .../styles/search.component.modal-move.scss | 3 +- .../styles/search.component.modal-zoomin.scss | 3 +- .../sidebar/_sidebar.component.theme.scss | 15 ++- .../components/sidebar/sidebar.component.scss | 19 +++- .../theme/components/user/user.component.scss | 5 +- src/framework/theme/styles/core/_mixins.scss | 51 +++++---- .../global/bootstrap/_button-group.scss | 107 ++++++------------ .../global/bootstrap/_custom-forms.scss | 3 +- .../styles/global/bootstrap/_dropdowns.scss | 13 ++- .../theme/styles/global/bootstrap/_forms.scss | 4 +- .../global/bootstrap/_icon-buttons.scss | 14 ++- .../styles/global/bootstrap/_input-group.scss | 45 +++----- .../styles/global/bootstrap/_modals.scss | 2 +- .../global/components/_toaster.theme.scss | 11 +- .../global/tables/_smart-table.theme.scss | 55 ++++----- .../styles/global/typography/_typography.scss | 19 +--- 27 files changed, 206 insertions(+), 234 deletions(-) diff --git a/src/framework/theme/components/actions/_actions.component.theme.scss b/src/framework/theme/components/actions/_actions.component.theme.scss index e076e2169e..e5d34588c0 100644 --- a/src/framework/theme/components/actions/_actions.component.theme.scss +++ b/src/framework/theme/components/actions/_actions.component.theme.scss @@ -16,12 +16,8 @@ padding: 0 nb-theme(actions-padding); &:first-child { - @include rtl-prop( - border-left, - border-right, - none!important, - 1px solid nb-theme(actions-separator) - ); + @include nb-ltr(border-left, none!important); + @include nb-rtl(border-right, none!important); } a.icon-container { @@ -35,12 +31,9 @@ font-size: nb-theme(actions-size-small); } - @include rtl-prop( - border-left, - border-right, - 1px solid nb-theme(actions-separator), - none - ); + @include nb-ltr(border-left, 1px solid nb-theme(actions-separator)); + @include nb-rtl(border-right, 1px solid nb-theme(actions-separator)); + background: transparent; } @@ -50,12 +43,8 @@ color: nb-theme(actions-bg); } - @include rtl-prop( - border-left, - border-right, - 1px solid nb-theme(actions-separator), - none - ); + @include nb-ltr(border-left, 1px solid nb-theme(actions-separator)); + @include nb-rtl(border-right, 1px solid nb-theme(actions-separator)); } } diff --git a/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss b/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss index f5ae8ac829..3d4955b4b2 100644 --- a/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss +++ b/src/framework/theme/components/card/flip-card/_flip-card.component.theme.scss @@ -6,6 +6,7 @@ } .flipcard-body .front-container { - @include rtl-prop(margin-right, margin-left, -100%, auto); + @include nb-ltr(margin-right, -100%); + @include nb-rtl(margin-left, -100%); } } diff --git a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss index 8ef91697be..7ab5938e6f 100644 --- a/src/framework/theme/components/checkbox/_checkbox.component.theme.scss +++ b/src/framework/theme/components/checkbox/_checkbox.component.theme.scss @@ -35,7 +35,8 @@ // locally used mixin @mixin description-style { color: nb-theme(color-fg-heading); - @include rtl-prop(padding-left, padding-right, 0.25rem, 0); + @include nb-ltr(padding-left, 0.25rem); + @include nb-rtl(padding-right, 0.25rem); } @mixin nb-checkbox-theme() { @@ -60,7 +61,8 @@ position: absolute; top: 50%; transform: translateY(-50%); - @include rtl-prop(left, right, 0, auto); + @include nb-ltr(left, 0); + @include nb-rtl(right, 0); flex: none; display: flex; justify-content: center; diff --git a/src/framework/theme/components/context-menu/context-menu.component.scss b/src/framework/theme/components/context-menu/context-menu.component.scss index 8fe1af38c2..721139813c 100644 --- a/src/framework/theme/components/context-menu/context-menu.component.scss +++ b/src/framework/theme/components/context-menu/context-menu.component.scss @@ -35,15 +35,17 @@ .menu-title { padding: 0.375rem 3rem; - @include rtl-only(text-align, right); + @include nb-rtl(text-align, right); } .menu-icon ~ .menu-title { - @include rtl-prop(padding-left, padding-right, 0, 3rem); + @include nb-ltr(padding-left, 0); + @include nb-rtl(padding-right, 0); } .menu-icon:first-child { - @include rtl-prop(padding-left, padding-right, 1rem, 3rem); + @include nb-ltr(padding-left, 1rem); + @include nb-rtl(padding-right, 1rem); } } } diff --git a/src/framework/theme/components/layout/layout.component.scss b/src/framework/theme/components/layout/layout.component.scss index 4123d29783..41416c978b 100644 --- a/src/framework/theme/components/layout/layout.component.scss +++ b/src/framework/theme/components/layout/layout.component.scss @@ -8,7 +8,8 @@ :host { - @include rtl(text-align, left, right); + @include nb-ltr(text-align, left); + @include nb-rtl(text-align, right); -webkit-font-smoothing: antialiased; @@ -42,10 +43,12 @@ /deep/ nb-sidebar { &.left { - @include rtl(order, 0, 2); + @include nb-ltr(order, 0); + @include nb-rtl(order, 2); } &.right { - @include rtl(order, 2, 0); + @include nb-ltr(order, 2); + @include nb-rtl(order, 0); } &.end { order: 2; @@ -85,7 +88,8 @@ flex: 1 0; min-width: 0; // fix for flexbug https://github.com/philipwalton/flexbugs#flexbug-1 &.left { - @include rtl(order, 0, 2); + @include nb-ltr(order, 0); + @include nb-rtl(order, 2); } &.start { order: 0; diff --git a/src/framework/theme/components/menu/menu.component.scss b/src/framework/theme/components/menu/menu.component.scss index 4bcbdbea6a..e9e9635e3b 100644 --- a/src/framework/theme/components/menu/menu.component.scss +++ b/src/framework/theme/components/menu/menu.component.scss @@ -24,7 +24,7 @@ .menu-title { flex: 1; - @include rtl-only(text-align, right); + @include nb-rtl(text-align, right); } } } diff --git a/src/framework/theme/components/search/styles/search.component.column-curtain.scss b/src/framework/theme/components/search/styles/search.component.column-curtain.scss index ae011d1aa0..0bf03fb2a4 100644 --- a/src/framework/theme/components/search/styles/search.component.column-curtain.scss +++ b/src/framework/theme/components/search/styles/search.component.column-curtain.scss @@ -43,7 +43,8 @@ button { position: absolute; top: 2rem; - @include rtl-prop(right, left, 2rem, auto); + @include nb-ltr(right, 2rem); + @include nb-rtl(left, 2rem); font-size: 2.5rem; opacity: 0; transition: opacity 0.5s; diff --git a/src/framework/theme/components/search/styles/search.component.curtain.scss b/src/framework/theme/components/search/styles/search.component.curtain.scss index e9e728fbf1..63e84fd849 100644 --- a/src/framework/theme/components/search/styles/search.component.curtain.scss +++ b/src/framework/theme/components/search/styles/search.component.curtain.scss @@ -37,7 +37,8 @@ font-size: 2.5rem; position: absolute; top: 3rem; - @include rtl-prop(right, left, 3rem, auto); + @include nb-ltr(right, 3rem); + @include nb-rtl(left, 3rem); transition: opacity 0.1s; transition-delay: 0.3s; } diff --git a/src/framework/theme/components/search/styles/search.component.layout-rotate.scss b/src/framework/theme/components/search/styles/search.component.layout-rotate.scss index 03617b7b7f..c50a9e3612 100644 --- a/src/framework/theme/components/search/styles/search.component.layout-rotate.scss +++ b/src/framework/theme/components/search/styles/search.component.layout-rotate.scss @@ -50,7 +50,8 @@ button { position: absolute; top: 3rem; - @include rtl-prop(right, left, 3rem, auto); + @include nb-ltr(right, 3rem); + @include nb-rtl(left, 3rem); font-size: 2.5rem; opacity: 0; transform: scale3d(0.8, 0.8, 1); diff --git a/src/framework/theme/components/search/styles/search.component.modal-drop.scss b/src/framework/theme/components/search/styles/search.component.modal-drop.scss index 6b84ae2a18..c910d387f8 100644 --- a/src/framework/theme/components/search/styles/search.component.modal-drop.scss +++ b/src/framework/theme/components/search/styles/search.component.modal-drop.scss @@ -50,7 +50,8 @@ font-size: 2.5rem; position: absolute; top: 3rem; - @include rtl-prop(right, left, 3rem, auto); + @include nb-ltr(right, 3rem); + @include nb-rtl(left, 3rem); display: block; opacity: 0; transition: opacity 0.4s; diff --git a/src/framework/theme/components/search/styles/search.component.modal-half.scss b/src/framework/theme/components/search/styles/search.component.modal-half.scss index 1c2c9cc749..8400b362db 100644 --- a/src/framework/theme/components/search/styles/search.component.modal-half.scss +++ b/src/framework/theme/components/search/styles/search.component.modal-half.scss @@ -51,7 +51,8 @@ font-size: 2.5rem; position: absolute; top: 3rem; - @include rtl-prop(right, left, 3rem, auto); + @include nb-ltr(right, 3rem); + @include nb-rtl(left, 3rem); display: block; z-index: 100; opacity: 0; diff --git a/src/framework/theme/components/search/styles/search.component.modal-move.scss b/src/framework/theme/components/search/styles/search.component.modal-move.scss index eb608160e7..550e75d362 100644 --- a/src/framework/theme/components/search/styles/search.component.modal-move.scss +++ b/src/framework/theme/components/search/styles/search.component.modal-move.scss @@ -40,7 +40,8 @@ button { position: absolute; top: 3rem; - @include rtl-prop(right, left, 3rem, auto); + @include nb-ltr(right, 3rem); + @include nb-rtl(left, 3rem); font-size: 2.5rem; opacity: 0; transition: opacity 0.5s; diff --git a/src/framework/theme/components/search/styles/search.component.modal-zoomin.scss b/src/framework/theme/components/search/styles/search.component.modal-zoomin.scss index 176383857e..384f6003ae 100644 --- a/src/framework/theme/components/search/styles/search.component.modal-zoomin.scss +++ b/src/framework/theme/components/search/styles/search.component.modal-zoomin.scss @@ -100,7 +100,8 @@ button { position: absolute; top: 3rem; - @include rtl-prop(right, left, 3rem, auto); + @include nb-ltr(right, 3rem); + @include nb-rtl(left, 3rem); font-size: 2.5rem; } diff --git a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss index bc12fa70d9..70a1feb629 100644 --- a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss +++ b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss @@ -75,7 +75,8 @@ &::before { position: absolute; content: ''; - @include rtl-prop(left, right, 0, auto); + @include nb-ltr(left, 0); + @include nb-rtl(right, 0); top: 0; height: 100%; width: 4px; @@ -134,19 +135,23 @@ } &.start.fixed ~ .content { - @include rtl-prop(margin-left, margin-right, nb-theme(sidebar-width-compact), 0); + @include nb-ltr(margin-left, nb-theme(sidebar-width-compact)); + @include nb-rtl(margin-right, nb-theme(sidebar-width-compact)); } &.fixed.end ~ .content { - @include rtl-prop(margin-right, margin-left, nb-theme(sidebar-width-compact), 0); + @include nb-ltr(margin-right,nb-theme(sidebar-width-compact)); + @include nb-rtl(margin-left, nb-theme(sidebar-width-compact)); } &.start.fixed ~ .content.center { - @include rtl-prop(padding-left, padding-right, nb-theme(sidebar-width-compact), 0); + @include nb-ltr(padding-left, nb-theme(sidebar-width-compact)); + @include nb-rtl(padding-right, nb-theme(sidebar-width-compact)); } &.fixed.end ~ .content.center { - @include rtl-prop(padding-right, padding-left, nb-theme(sidebar-width-compact), 0); + @include nb-ltr(padding-right, nb-theme(sidebar-width-compact)); + @include nb-rtl(padding-left, nb-theme(sidebar-width-compact)); } } diff --git a/src/framework/theme/components/sidebar/sidebar.component.scss b/src/framework/theme/components/sidebar/sidebar.component.scss index 54a1266ebd..953c77cc41 100644 --- a/src/framework/theme/components/sidebar/sidebar.component.scss +++ b/src/framework/theme/components/sidebar/sidebar.component.scss @@ -28,15 +28,22 @@ } &.right { - @include rtl(order, 4, 0); + @include nb-ltr(order, 4); + @include nb-rtl(order, 0); margin-right: 0; margin-left: auto; } &.end { order: 4; - @include rtl-prop(margin-right, margin-left, 0, auto); - @include rtl-prop(margin-left, margin-right, auto, 0); + @include nb-ltr() { + margin-right: 0; + margin-left: auto; + }; + @include nb-rtl() { + margin-left: 0; + margin-right: auto; + }; } // TODO: in this case this will won't work when header is not fixed and sidebar is @@ -55,10 +62,12 @@ } &.fixed.start { - @include rtl-prop(left, right, 0, auto); + @include nb-ltr(left, 0); + @include nb-rtl(right, 0); } &.fixed.end { - @include rtl-prop(right, left, 0, auto); + @include nb-ltr(right, 0); + @include nb-rtl(left, 0); } /deep/ nb-sidebar-footer { diff --git a/src/framework/theme/components/user/user.component.scss b/src/framework/theme/components/user/user.component.scss index fc4962963d..76b1fbc015 100644 --- a/src/framework/theme/components/user/user.component.scss +++ b/src/framework/theme/components/user/user.component.scss @@ -38,10 +38,11 @@ .user-name, .user-title { - @include rtl-only(text-align, right); + @include nb-rtl(text-align, right); } .info-container { - @include rtl-prop(margin-left, margin-right, 0.5rem, 0); + @include nb-ltr(margin-left, 0.5rem); + @include nb-rtl(margin-right, 0.5rem); } } diff --git a/src/framework/theme/styles/core/_mixins.scss b/src/framework/theme/styles/core/_mixins.scss index d89333e7d1..7119cf5d3a 100644 --- a/src/framework/theme/styles/core/_mixins.scss +++ b/src/framework/theme/styles/core/_mixins.scss @@ -194,35 +194,42 @@ } } -@mixin rtl-prop($ltr-prop, $rtl-prop, $value, $reset-value: null) { - #{$ltr-prop}: $value; +@mixin _prepend-with-selector($selector, $prop: null, $value: null) { + /* + @at-root used to place result of concatenation of two selectors ($selector with '&') + at a very top level, i.e. do not nest inside selector where mixin was called. + + consider next example: + :host { + @include _prepend-with-selector('.prepend-class') { + ... + } + } - @at-root #{selector-append('[dir=rtl]', &)}, - [dir=rtl] & { - #{$ltr-prop}: $reset-value; - #{$rtl-prop}: $value; - } -} + result without @at-root + :host .prepend-class:host -@mixin rtl($prop, $ltr-value, $rtl-value) { - #{$prop}: $ltr-value; + result with @at-root + .prepend-class:host + */ + @at-root #{selector-append($selector, &)}, + #{$selector} & { + @if $prop != null { + #{$prop}: $value; + } - @at-root #{selector-append('[dir=rtl]', &)}, - [dir=rtl] & { - #{$prop}: $rtl-value; + @content; } } -@mixin rtl-only($prop, $value) { - @at-root #{selector-append('[dir=rtl]', &)}, - [dir=rtl] & { - #{$prop}: $value; +@mixin nb-ltr($prop: null, $value: null) { + @include _prepend-with-selector(':not([dir=rtl])', $prop, $value) { + @content; } } -@mixin ltr-only($prop, $value) { - @at-root #{selector-append(':not([dir=rtl])', &)}, - :not([dir=rtl]) & { - #{$prop}: $value; - } +@mixin nb-rtl($prop: null, $value: null) { + @include _prepend-with-selector('[dir=rtl]', $prop, $value) { + @content; + }; } diff --git a/src/framework/theme/styles/global/bootstrap/_button-group.scss b/src/framework/theme/styles/global/bootstrap/_button-group.scss index 4d67a3146d..ee5c4934e1 100644 --- a/src/framework/theme/styles/global/bootstrap/_button-group.scss +++ b/src/framework/theme/styles/global/bootstrap/_button-group.scss @@ -94,69 +94,45 @@ .btn-group:not(.btn-divided-group) > .btn:not(.dropdown-toggle) { &:first-child { - @include rtl-prop( - border-top-left-radius, - border-top-right-radius, - nb-theme(btn-border-radius), - 0 - ); - @include rtl-prop( - border-bottom-left-radius, - border-bottom-right-radius, - nb-theme(btn-border-radius), - 0 - ); + @include nb-ltr() { + border-top-left-radius: nb-theme(btn-border-radius); + border-bottom-left-radius: nb-theme(btn-border-radius); + }; + @include nb-rtl() { + border-top-right-radius: nb-theme(btn-border-radius); + border-bottom-right-radius: nb-theme(btn-border-radius); + }; } &:last-child { - @include rtl-prop( - border-top-right-radius, - border-top-left-radius, - nb-theme(btn-border-radius), - 0 - ); - @include rtl-prop( - border-bottom-right-radius, - border-bottom-left-radius, - nb-theme(btn-border-radius), - 0 - ); + @include nb-ltr() { + 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); + }; } } .btn-group.dropdown { & > .btn:first-of-type.dropdown-toggle { - @include rtl-prop( - border-top-left-radius, - border-top-right-radius, - nb-theme(btn-border-radius), - 0 - ); + @include nb-ltr(border-top-left-radius, nb-theme(btn-border-radius)); + @include nb-rtl(border-top-right-radius, nb-theme(btn-border-radius)); } & > .btn:last-of-type.dropdown-toggle { - @include rtl-prop( - border-top-right-radius, - border-top-left-radius, - nb-theme(btn-border-radius), - 0 - ); + @include nb-ltr(border-top-right-radius, nb-theme(btn-border-radius)); + @include nb-rtl(border-top-left-radius, nb-theme(btn-border-radius)); } &:not(.show) { & > .btn:first-of-type.dropdown-toggle { - @include rtl-prop( - border-bottom-left-radius, - border-bottom-right-radius, - nb-theme(btn-border-radius), - 0 - ); + @include nb-ltr(border-bottom-left-radius, nb-theme(btn-border-radius)); + @include nb-rtl(border-bottom-right-radius, nb-theme(btn-border-radius)); } & > .btn:last-of-type.dropdown-toggle { - @include rtl-prop( - border-bottom-right-radius, - border-bottom-left-radius, - nb-theme(btn-border-radius), - 0 - ); + @include nb-ltr(border-bottom-right-radius, nb-theme(btn-border-radius)); + @include nb-rtl(border-bottom-left-radius, nb-theme(btn-border-radius)); } } @@ -168,38 +144,22 @@ .btn-group.dropup { & > .btn:first-of-type.dropdown-toggle { - @include rtl-prop( - border-bottom-left-radius, - border-bottom-right-radius, - nb-theme(btn-border-radius), - 0 - ); + @include nb-ltr(border-bottom-left-radius, nb-theme(btn-border-radius)); + @include nb-rtl(border-bottom-right-radius, nb-theme(btn-border-radius)); } & > .btn:last-of-type.dropdown-toggle { - @include rtl-prop( - border-bottom-right-radius, - border-bottom-left-radius, - nb-theme(btn-border-radius), - 0 - ); + @include nb-ltr(border-bottom-right-radius, nb-theme(btn-border-radius)); + @include nb-rtl(border-bottom-left-radius, nb-theme(btn-border-radius)); } &:not(.show) { & > .btn:first-of-type.dropdown-toggle { - @include rtl-prop( - border-top-left-radius, - border-top-right-radius, - nb-theme(btn-border-radius), - 0 - ); + @include nb-ltr(border-top-left-radius, nb-theme(btn-border-radius)); + @include nb-rtl(border-top-right-radius, nb-theme(btn-border-radius)); } & > .btn:last-of-type.dropdown-toggle { - @include rtl-prop( - border-top-right-radius, - border-top-left-radius, - nb-theme(btn-border-radius), - 0 - ); + @include nb-ltr(border-top-right-radius, nb-theme(btn-border-radius)); + @include nb-rtl(border-top-left-radius, nb-theme(btn-border-radius)); } } @@ -301,7 +261,8 @@ .btn-divided-group { .btn:not(:first-child) { - @include rtl-prop(margin-left, margin-right, 0.5rem, 0); + @include nb-ltr(margin-left, 0.5rem); + @include nb-rtl(margin-right, 0.5rem); border-radius: nb-theme(btn-border-radius); } diff --git a/src/framework/theme/styles/global/bootstrap/_custom-forms.scss b/src/framework/theme/styles/global/bootstrap/_custom-forms.scss index d2003fb065..22659415f0 100644 --- a/src/framework/theme/styles/global/bootstrap/_custom-forms.scss +++ b/src/framework/theme/styles/global/bootstrap/_custom-forms.scss @@ -28,7 +28,8 @@ border: nb-theme(checkbox-border-size) solid nb-theme(checkbox-border-color); flex-shrink: 0; position: absolute; - @include rtl-prop(left, right, 0, auto); + @include nb-ltr(left, 0); + @include nb-rtl(right, 0); display: flex; justify-content: center; align-items: center; diff --git a/src/framework/theme/styles/global/bootstrap/_dropdowns.scss b/src/framework/theme/styles/global/bootstrap/_dropdowns.scss index 5db663e660..284326380a 100644 --- a/src/framework/theme/styles/global/bootstrap/_dropdowns.scss +++ b/src/framework/theme/styles/global/bootstrap/_dropdowns.scss @@ -103,7 +103,8 @@ .btn:first-child { width: 90%; - @include rtl(text-align, left, right); + @include nb-ltr(text-align, left); + @include nb-rtl(text-align, right); } .dropdown-toggle { @@ -126,15 +127,16 @@ .dropdown.btn-group.show, .dropup.btn-group.show { .btn:first-child { - @include ltr-only(border-bottom-left-radius, 0); - @include rtl-only(border-bottom-right-radius, 0); + @include nb-ltr(border-bottom-left-radius, 0); + @include nb-rtl(border-bottom-right-radius, 0); } } .dropdown, .dropup { .dropdown-toggle { width: 100%; - @include rtl(text-align, left, right); + @include nb-ltr(text-align, left); + @include nb-rtl(text-align, right); position: relative; } @@ -295,7 +297,8 @@ .dropdown-toggle::after { top: 50%; transform: translate(0, -50%); - @include rtl-prop(right, left, 0.75rem, auto); + @include nb-ltr(right, 0.75rem); + @include nb-rtl(left, 0.75rem); } } diff --git a/src/framework/theme/styles/global/bootstrap/_forms.scss b/src/framework/theme/styles/global/bootstrap/_forms.scss index 13dcc976ae..206a13d882 100644 --- a/src/framework/theme/styles/global/bootstrap/_forms.scss +++ b/src/framework/theme/styles/global/bootstrap/_forms.scss @@ -105,8 +105,8 @@ &.hint, &.error { - @include ltr-only(margin-left, 1rem); - @include rtl-only(margin-right, 1rem); + @include nb-ltr(margin-left, 1rem); + @include nb-rtl(margin-right, 1rem); } &.error { diff --git a/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss b/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss index 9f1bf91cd5..11a5bf28da 100644 --- a/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss +++ b/src/framework/theme/styles/global/bootstrap/_icon-buttons.scss @@ -20,12 +20,18 @@ } .btn-with-icon { - @include rtl(text-align, left, right); - @include ltr-only(padding-left, 1rem); - @include rtl-only(padding-right, 1rem); + @include nb-ltr() { + padding-left: 1rem; + text-align: left; + }; + @include nb-rtl() { + padding-right: 1rem; + text-align: right; + }; .icon { - @include rtl-prop(margin-right, margin-left, 1rem, 0); + @include nb-ltr(margin-right, 1rem); + @include nb-rtl(margin-left, 1rem); } } } diff --git a/src/framework/theme/styles/global/bootstrap/_input-group.scss b/src/framework/theme/styles/global/bootstrap/_input-group.scss index 301168e778..bbcc3ed625 100644 --- a/src/framework/theme/styles/global/bootstrap/_input-group.scss +++ b/src/framework/theme/styles/global/bootstrap/_input-group.scss @@ -19,7 +19,8 @@ padding: 0.25rem 1rem; color: nb-theme(form-control-placeholder-color); - @include rtl-prop(border-right, border-left, none, $form-control-border); + @include nb-ltr(border-right, none); + @include nb-rtl(border-left, none); } .input-group-addon { @@ -53,37 +54,27 @@ .input-group-addon:first-child, .input-group-prepend .btn:first-child, .input-group-btn .btn:first-child { - @include rtl-prop( - border-top-right-radius, - border-top-left-radius, - 0, - nb-theme(form-control-border-radius) - ); - - @include rtl-prop( - border-bottom-right-radius, - border-bottom-left-radius, - 0, - nb-theme(form-control-border-radius) - ); + @include nb-ltr() { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + }; + @include nb-rtl() { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + }; } .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 rtl-prop( - border-top-left-radius, - border-top-right-radius, - 0, - nb-theme(form-control-border-radius) - ); - - @include rtl-prop( - border-bottom-left-radius, - border-bottom-right-radius, - 0, - nb-theme(form-control-border-radius) - ); + @include nb-ltr() { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + }; + @include nb-rtl() { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + }; } .dropdown.show .btn.dropdown-toggle { diff --git a/src/framework/theme/styles/global/bootstrap/_modals.scss b/src/framework/theme/styles/global/bootstrap/_modals.scss index 73e4aec728..e3d575d9d5 100644 --- a/src/framework/theme/styles/global/bootstrap/_modals.scss +++ b/src/framework/theme/styles/global/bootstrap/_modals.scss @@ -32,7 +32,7 @@ @include nb-headings(); - @include rtl-only(flex-flow, row-reverse); + @include nb-rtl(flex-flow, row-reverse); .close { text-shadow: none; diff --git a/src/framework/theme/styles/global/components/_toaster.theme.scss b/src/framework/theme/styles/global/components/_toaster.theme.scss index af63ee972d..13a8885873 100644 --- a/src/framework/theme/styles/global/components/_toaster.theme.scss +++ b/src/framework/theme/styles/global/components/_toaster.theme.scss @@ -8,7 +8,8 @@ .toast-close-button { position: absolute; - @include rtl-prop(right, left, 0.15rem, auto); + @include nb-ltr(right, 0.15rem); + @include nb-rtl(left, 0.15rem); top: 0.2rem; opacity: 1; background-color: nb-theme(toaster-btn-close-bg); @@ -38,12 +39,12 @@ // have to use id selector for specifity /* stylelint-disable-next-line selector-max-id */ #toast-container > div.toast { - @include rtl-only(padding-left, 15px); - @include rtl-only(padding-right, 50px); + @include nb-rtl(padding-left, 15px); + @include nb-rtl(padding-right, 50px); } .toaster-icon { - @include rtl-only(right, 0); - @include rtl-only(background-position-x, 0); + @include nb-rtl(right, 0); + @include nb-rtl(background-position-x, 0); } .toast-success { background-color: nb-theme(toaster-success); diff --git a/src/framework/theme/styles/global/tables/_smart-table.theme.scss b/src/framework/theme/styles/global/tables/_smart-table.theme.scss index ba1de57f4d..228cfd449b 100644 --- a/src/framework/theme/styles/global/tables/_smart-table.theme.scss +++ b/src/framework/theme/styles/global/tables/_smart-table.theme.scss @@ -35,8 +35,8 @@ table tr.ng2-smart-titles { th { padding: nb-theme(smart-table-padding); - @include ltr-only(padding-right, 1.75rem); - @include rtl-only(padding-left, 1.75rem); + @include nb-ltr(padding-right, 1.75rem); + @include nb-rtl(padding-left, 1.75rem); } th a { @@ -53,7 +53,8 @@ border-width: 0.375rem; position: absolute; margin: 0; - @include rtl-prop(right, left, 0.75rem, auto); + @include nb-ltr(right, 0.75rem); + @include nb-rtl(left, 0.75rem); top: 50%; transform: translate(0, -50%); } @@ -183,12 +184,8 @@ li { &:not(:last-child) { - @include rtl-prop( - border-right, - border-left, - 1px solid nb-theme(smart-table-separator), - none - ); + @include nb-ltr(border-right, 1px solid nb-theme(smart-table-separator)); + @include nb-rtl(border-left, 1px solid nb-theme(smart-table-separator)); } a.page-link-prev, a.page-link-next { @@ -210,35 +207,27 @@ &:first-child { a, > span { - @include rtl-prop( - border-top-left-radius, - border-top-right-radius, - nb-theme(smart-table-border-radius), - 0 - ); - @include rtl-prop( - border-bottom-left-radius, - border-bottom-right-radius, - nb-theme(smart-table-border-radius), - 0 - ); + @include nb-ltr() { + border-top-left-radius: nb-theme(smart-table-border-radius); + border-bottom-left-radius: nb-theme(smart-table-border-radius); + }; + @include nb-rtl() { + border-top-right-radius: nb-theme(smart-table-border-radius); + border-bottom-right-radius: nb-theme(smart-table-border-radius); + }; } } &:last-child { a, > span { - @include rtl-prop( - border-top-right-radius, - border-top-left-radius, - nb-theme(smart-table-border-radius), - 0 - ); - @include rtl-prop( - border-bottom-right-radius, - border-bottom-left-radius, - nb-theme(smart-table-border-radius), - 0 - ); + @include nb-ltr() { + border-top-right-radius: nb-theme(smart-table-border-radius); + border-bottom-right-radius: nb-theme(smart-table-border-radius); + }; + @include nb-rtl() { + border-top-left-radius: nb-theme(smart-table-border-radius); + border-bottom-left-radius: nb-theme(smart-table-border-radius); + }; } } diff --git a/src/framework/theme/styles/global/typography/_typography.scss b/src/framework/theme/styles/global/typography/_typography.scss index f76ab77886..37c2791f4b 100644 --- a/src/framework/theme/styles/global/typography/_typography.scss +++ b/src/framework/theme/styles/global/typography/_typography.scss @@ -155,23 +155,15 @@ font-size: nb-theme(font-size); color: nb-theme(color-fg-text); - @include rtl-prop( - border-left, - border-right, - 0.25rem solid nb-theme(color-fg-highlight), - 0 - ); + @include nb-ltr(border-left, 0.25rem solid nb-theme(color-fg-highlight)); + @include nb-rtl(border-right, 0.25rem solid nb-theme(color-fg-highlight)); } .blockquote-reverse { font-size: nb-theme(font-size); color: nb-theme(color-fg-text); - @include rtl-prop( - border-right, - border-left, - 0.25rem solid nb-theme(color-fg-highlight), - 0 - ); + @include nb-ltr(border-right, 0.25rem solid nb-theme(color-fg-highlight)); + @include nb-rtl(border-left, 0.25rem solid nb-theme(color-fg-highlight)); } .blockquote-footer { color: nb-theme(color-fg); @@ -208,7 +200,8 @@ } ol,ul { - @include rtl-prop(padding-left, padding-right, 1.25rem, 0); + @include nb-ltr(padding-left, 1.25rem); + @include nb-rtl(padding-right, 1.25rem); } .alert { From 6bb6b130da37a98162e94bcd7340cbe966f83666 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Fri, 20 Apr 2018 17:07:42 +0300 Subject: [PATCH 75/89] refactor(theming): use :host instead of :host-context To be able use rtl mixins in nebular and ngx-admin in .component.scss and .theme.scss. We cann't nest multiple host selectors due to big amount of bugs. --- src/framework/theme/styles/_theming.scss | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/framework/theme/styles/_theming.scss b/src/framework/theme/styles/_theming.scss index e3918b229c..e9d06383a3 100644 --- a/src/framework/theme/styles/_theming.scss +++ b/src/framework/theme/styles/_theming.scss @@ -112,9 +112,11 @@ $nb-themes-export: () !global; $themes-to-install: get-enabled-themes(); @each $theme-name, $theme in $themes-to-install { - :host-context(#{$selector-prefix}.nb-theme-#{$theme-name}) { - $theme: set-global-theme-vars($theme, $theme-name); - @content; + .nb-theme-#{$theme-name} { + :host { + $theme: set-global-theme-vars($theme, $theme-name); + @content; + } } } } From 521b2f18909f45b920acccc31a6ef3effa438826 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Wed, 25 Apr 2018 12:58:33 +0300 Subject: [PATCH 76/89] style: remove unused parameter --- src/framework/theme/styles/_theming.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/theme/styles/_theming.scss b/src/framework/theme/styles/_theming.scss index e9d06383a3..4c11840181 100644 --- a/src/framework/theme/styles/_theming.scss +++ b/src/framework/theme/styles/_theming.scss @@ -107,7 +107,7 @@ $nb-themes-export: () !global; } // TODO: we hide :host inside of it which is not obvious -@mixin nb-install-component($selector-prefix: '') { +@mixin nb-install-component() { $themes-to-install: get-enabled-themes(); From 9ee3b2457020c8bc267836a589465016f56dee2c Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Wed, 25 Apr 2018 14:14:26 +0300 Subject: [PATCH 77/89] refactor: rewrite in one-line selector and add comments --- src/framework/theme/styles/_theming.scss | 28 +++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/framework/theme/styles/_theming.scss b/src/framework/theme/styles/_theming.scss index 4c11840181..b7a34e574f 100644 --- a/src/framework/theme/styles/_theming.scss +++ b/src/framework/theme/styles/_theming.scss @@ -112,11 +112,29 @@ $nb-themes-export: () !global; $themes-to-install: get-enabled-themes(); @each $theme-name, $theme in $themes-to-install { - .nb-theme-#{$theme-name} { - :host { - $theme: set-global-theme-vars($theme, $theme-name); - @content; - } + /* + :host can be prefixed + https://github.com/angular/angular/blob/8d0ee34939f14c07876d222c25b405ed458a34d3/packages/compiler/src/shadow_css.ts#L441 + + We have to use :host insted of :host-context($theme), to be able to prefix theme class + with something defined inside of @content, by prefixing &. + For example this scss code: + .nb-theme-default { + .some-selector & { + ... + } + } + Will result in next css: + .some-selector .nb-theme-default { + ... + } + + It doesn't work with :host-context because angular splitting it in two selectors and removes + prefix in one of the selectors. + */ + .nb-theme-#{$theme-name} :host { + $theme: set-global-theme-vars($theme, $theme-name); + @content; } } } From 45e52ab8891ff04a84493eca5f9e63ee3a3c78aa Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Wed, 25 Apr 2018 14:15:26 +0300 Subject: [PATCH 78/89] refactor(direction-service): set dir attribute on document --- .../components/layout/layout.component.ts | 3 +-- src/framework/theme/styles/core/_mixins.scss | 20 +------------------ 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/framework/theme/components/layout/layout.component.ts b/src/framework/theme/components/layout/layout.component.ts index 4b1af88241..4c3010e255 100644 --- a/src/framework/theme/components/layout/layout.component.ts +++ b/src/framework/theme/components/layout/layout.component.ts @@ -378,8 +378,7 @@ export class NbLayoutComponent implements AfterViewInit, OnInit, OnDestroy { this.layoutDirectionService.onDirectionChange() .pipe(takeWhile(() => this.alive)) .subscribe(direction => { - const { body } = this.document; - this.renderer.setAttribute(body, 'dir', direction); + this.renderer.setProperty(this.document, 'dir', direction); }); this.afterViewInit$.next(true); diff --git a/src/framework/theme/styles/core/_mixins.scss b/src/framework/theme/styles/core/_mixins.scss index 7119cf5d3a..0a09a64468 100644 --- a/src/framework/theme/styles/core/_mixins.scss +++ b/src/framework/theme/styles/core/_mixins.scss @@ -195,24 +195,6 @@ } @mixin _prepend-with-selector($selector, $prop: null, $value: null) { - /* - @at-root used to place result of concatenation of two selectors ($selector with '&') - at a very top level, i.e. do not nest inside selector where mixin was called. - - consider next example: - :host { - @include _prepend-with-selector('.prepend-class') { - ... - } - } - - result without @at-root - :host .prepend-class:host - - result with @at-root - .prepend-class:host - */ - @at-root #{selector-append($selector, &)}, #{$selector} & { @if $prop != null { #{$prop}: $value; @@ -223,7 +205,7 @@ } @mixin nb-ltr($prop: null, $value: null) { - @include _prepend-with-selector(':not([dir=rtl])', $prop, $value) { + @include _prepend-with-selector('[dir=ltr]', $prop, $value) { @content; } } From 29a80a00bcb9aaa59b9ffce3d7fd171e1703961e Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Wed, 25 Apr 2018 14:54:26 +0300 Subject: [PATCH 79/89] test(layout-component): add direction setting test --- e2e/layout.e2e-spec.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/e2e/layout.e2e-spec.ts b/e2e/layout.e2e-spec.ts index f0f2ff2163..de7febf6d0 100644 --- a/e2e/layout.e2e-spec.ts +++ b/e2e/layout.e2e-spec.ts @@ -155,4 +155,10 @@ describe('nb-layout', () => { }) }); }); + + it('should set default document direction', () => { + browser.executeScript('return document.dir').then(function (direction) { + expect(direction).toBe('ltr'); + }); + }); }); From b92c05674803f9b13deb6b42b04dada11252b1c4 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Sat, 28 Apr 2018 12:04:35 +0300 Subject: [PATCH 80/89] docs(rtl): add bidi support entry in dev docs --- DEV_DOCS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DEV_DOCS.md b/DEV_DOCS.md index fd154f6619..c116479456 100644 --- a/DEV_DOCS.md +++ b/DEV_DOCS.md @@ -20,6 +20,7 @@ - for the override styles - registered in a list of overrides - component *.theme registered in a list of component themes - looks great on all default themes +- supports bidirectionality - requires approval from several core team contributors # Objectives From 386c627caabec36f628c777215fce6292031a574 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Sat, 28 Apr 2018 12:25:11 +0300 Subject: [PATCH 81/89] style: add bidirectionality implemetation longread --- src/framework/theme/styles/core/_mixins.scss | 117 +++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/src/framework/theme/styles/core/_mixins.scss b/src/framework/theme/styles/core/_mixins.scss index 0a09a64468..5bc246d5bb 100644 --- a/src/framework/theme/styles/core/_mixins.scss +++ b/src/framework/theme/styles/core/_mixins.scss @@ -194,6 +194,123 @@ } } +/* + +According to the specification (https://www.w3.org/TR/css-scoping-1/#host-selector) +:host and :host-context are pseudo-classes. So we assume they could be combined, +like other pseudo-classes, even same ones. +For example: ':nth-of-type(2n):nth-of-type(even)'. + +Ideal solution would be to prepend any selector with :host-context([dir=rtl]). +Then nebular components will behave as an html element and respond to [dir] attribute on any level, +so direction could be overridden on any component level. + +Implementation code: + +@mixin nb-rtl() { + // add # to scss interpolation statement. + // it works in comments and we can't use it here + @at-root {selector-append(':host-context([dir=rtl])', &)} { + @content; + } +} + +And when we call it somewhere: + +:host { + .some-class { + @include nb-rtl() { + ... + } + } +} +:host-context(...) { + .some-class { + @include nb-rtl() { + ... + } + } +} + +Result will look like: + +:host-context([dir=rtl]):host .some-class { + ... +} +:host-context([dir=rtl]):host-context(...) .some-class { + ... +} + +* + Side note: + :host-context():host selector are valid. https://lists.w3.org/Archives/Public/www-style/2015Feb/0305.html + + :host-context([dir=rtl]):host-context(...) should match any permutation, + so order is not important. +* + + +Currently, there're two problems with this approach: + +First, is that we can't combine :host, :host-context. Angular bugs #14349, #19199. +For the moment of writing, the only possible way is: +:host { + :host-context(...) { + ... + } +} +It doesn't work for us because mixin could be called somewhere deeper, like: +:host { + p { + @include nb-rtl() { ... } + } +} +We are not able to go up to :host level to place content passed to mixin. + +The second problem is that we only can be sure that we appending :host-context([dir=rtl]) to another +:host/:host-context pseudo-class when called in theme files (*.theme.scss). + * + Side note: + Currently, nb-install-component uses another approach where :host prepended with the theme name + (https://github.com/angular/angular/blob/5b96078624b0a4760f2dbcf6fdf0bd62791be5bb/packages/compiler/src/shadow_css.ts#L441), + but it was made to be able to use current realization of rtl and it can be rewritten back to + :host-context($theme) once we will be able to use multiple shadow selectors. + * +But when it's called in *.component.scss we can't be sure, that selector starts with :host/:host-context, +because angular allows omitting pseudo-classes if we don't need to style :host component itself. +We can break such selectors, by just appending :host-context([dir=rtl]) to them. + *** + Possible solution + check if we in theme by some theme variables and if so append, otherwise nest like + @at-root :host-context([dir=rtl]) { + // add # to scss interpolation statement. + // it works in comments and we can't use it here + {&} { + @content; + } + } + What if :host specified? Can we add space in :host-context(...) :host? + Or maybe add :host selector anyway? If multiple :host selectors are allowed + *** + + +Problems with the current approach. + +1. Direction can be applied only on document level, because mixin prepends theme class, +which placed on the body. +2. *.component.scss styles should be in :host selector. Otherwise angular will add host +attribute to [dir=rtl] attribute as well. + + +General problems. + +Ltr is default document direction, but for proper work of nb-ltr (means ltr only), +[dir=ltr] should be specified at least somewhere. ':not([dir=rtl]' not applicable here, +because it's satisfy any parent, that don't have [dir=rtl] attribute. +Previous approach was to use single rtl mixin and reset ltr properties to initial value. +But sometimes it's hard to find, what the previous value should be. And such mixin call looks too verbose. +*/ + @mixin _prepend-with-selector($selector, $prop: null, $value: null) { #{$selector} & { @if $prop != null { From c9973984dfd27c447b1ff07898b57d2ee582e159 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 7 May 2018 17:33:12 +0300 Subject: [PATCH 82/89] docs(rtl): add rtl system overview --- docs/articles/rtl.md | 53 ++++++++++++++++++++++++++++++++++++++++++++ docs/structure.ts | 28 +++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 docs/articles/rtl.md diff --git a/docs/articles/rtl.md b/docs/articles/rtl.md new file mode 100644 index 0000000000..fd2b692398 --- /dev/null +++ b/docs/articles/rtl.md @@ -0,0 +1,53 @@ +All Nebular components were updated to support RTL out of the box. + +Now every component, that previously could be positioned via some setting, besides old `left` and `right` options, also support logical `start` and `end` properties, similar to flexbox. Value of `start` and `end` depends on current layout direction. For LTR it's left, for RTL - right. + +You can set document direction via last parameter `forRoot` method of `NbThemeModule`. Supported values are 'ltr' and 'rtl'. +```typescript +@NgModule({ + imports: [ + NbThemeModule.forRoot(nbThemeOptions, nbJSThemes, nbMediaBreakpoints, 'rtl') + ] +}) +``` +Default value is `ltr`. +
+
Note
+
+ 1. Works only in layout component +
+
+ +If you need to change direction dynamically, get current value or listen to changes of direction, Nebular provides `NbLayoutDirectionService`. +
+
Note
+
+ 1. Listen only to changes made through service itself + 2. Works only in layout component. +
+
+ +To help you add RTL support to your custom components, Nebular provides you with two scss mixins: `nb-lrt` and `nb-rtl`. You can use them to alter values of css properties, which don't support logical values, like paddings, margins, etc. You can pass single property and value as arguments, pass multiple statements as a content of mixin or both. For example: +```scss +:host { + nb-ltr(padding-left, 1em); + nb-rtl(padding-right, 1em); +} +``` +```scss +:host { + nb-ltr() { + padding-left: 1em; + }; + nb-rtl() { + padding-right: 1em; + }; +} +``` + +
+
Note
+
+ One thing to note, mixins should be called only inside of `:host` mixin or `nb-install-component`. +
+
diff --git a/docs/structure.ts b/docs/structure.ts index 6e3bd5dbf7..076ebf1e0f 100644 --- a/docs/structure.ts +++ b/docs/structure.ts @@ -648,4 +648,32 @@ export const STRUCTURE = [ }, ], }, + { + type: 'section', + name: 'Usability', + children: [ + { + type: 'page', + name: 'RTL', + children: [ + { + type: 'block', + block: 'markdown', + source: 'rtl.md', + }, + ], + }, + { + type: 'page', + name: 'NbLayoutDirectionService', + children: [ + { + type: 'block', + block: 'component', + source: 'NbLayoutDirectionService', + }, + ], + }, + ], + }, ]; From 22699ff14ab1a0c633ba13b2688c72a7030d7ab4 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 7 May 2018 18:30:50 +0300 Subject: [PATCH 83/89] docs(direction-service): update onDirectionChange description --- src/framework/theme/services/direction.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index ca06829340..61692b73c9 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -64,7 +64,8 @@ export class NbLayoutDirectionService { } /** - * Triggers direction change + * Triggered when direction was changed. + * @returns Observable. */ onDirectionChange(): Observable { return this.$directionChange.pipe(share()); From 213fb58299862c358203b57b87ca24a5a12d0554 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 7 May 2018 18:31:46 +0300 Subject: [PATCH 84/89] docs(rtl): merge rtl and direction service pages in one --- docs/structure.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/structure.ts b/docs/structure.ts index 076ebf1e0f..eeae0c905e 100644 --- a/docs/structure.ts +++ b/docs/structure.ts @@ -654,19 +654,13 @@ export const STRUCTURE = [ children: [ { type: 'page', - name: 'RTL', + name: 'Right-to-left (RTL)', children: [ { type: 'block', block: 'markdown', source: 'rtl.md', }, - ], - }, - { - type: 'page', - name: 'NbLayoutDirectionService', - children: [ { type: 'block', block: 'component', From 2ee07de6cda71e8cd99ab1f32bcac655ed0a6bfc Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 7 May 2018 18:36:36 +0300 Subject: [PATCH 85/89] docs(rtl): remove temporary notes --- docs/articles/rtl.md | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/docs/articles/rtl.md b/docs/articles/rtl.md index fd2b692398..8b6a62cd10 100644 --- a/docs/articles/rtl.md +++ b/docs/articles/rtl.md @@ -1,8 +1,14 @@ -All Nebular components were updated to support RTL out of the box. +All Nebular components support RTL out of the box. -Now every component, that previously could be positioned via some setting, besides old `left` and `right` options, also support logical `start` and `end` properties, similar to flexbox. Value of `start` and `end` depends on current layout direction. For LTR it's left, for RTL - right. +The components that accept a position as a setting now also support logical start and end values, similar to flexbox. Value of start and end depends on current layout direction. For LTR it's left and for RTL - right. +For instance, if we need the sidebar to be positioned logically depending on a language direction, then instead of setting it to left we can set its position to start: + +```html + +``` + +Document direction could be set through the NbThemeModule.forRoot call. Supported values are 'ltr' and 'rtl'. -You can set document direction via last parameter `forRoot` method of `NbThemeModule`. Supported values are 'ltr' and 'rtl'. ```typescript @NgModule({ imports: [ @@ -11,19 +17,11 @@ You can set document direction via last parameter `forRoot` method of `NbThemeMo }) ``` Default value is `ltr`. -
-
Note
-
- 1. Works only in layout component -
-
-If you need to change direction dynamically, get current value or listen to changes of direction, Nebular provides `NbLayoutDirectionService`.
Note
- 1. Listen only to changes made through service itself - 2. Works only in layout component. + Components must be placed inside of the `` component to correctly support language direction.
@@ -45,9 +43,6 @@ To help you add RTL support to your custom components, Nebular provides you with } ``` -
-
Note
-
- One thing to note, mixins should be called only inside of `:host` mixin or `nb-install-component`. -
-
+Please note, the mixins are only available within component `:host` selector or `nb-install-component()` mixin if used. + +If you need to change direction dynamically, get current value or listen to changes of direction, Nebular provides `NbLayoutDirectionService`. From 01a86dc36c7930709c182a62d9c7697b348b357a Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 7 May 2018 19:29:11 +0300 Subject: [PATCH 86/89] docs(rtl): fix direction service docs --- src/framework/theme/services/direction.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/framework/theme/services/direction.service.ts b/src/framework/theme/services/direction.service.ts index 61692b73c9..cc3192425e 100644 --- a/src/framework/theme/services/direction.service.ts +++ b/src/framework/theme/services/direction.service.ts @@ -55,9 +55,9 @@ export class NbLayoutDirectionService { } /** - * Sets layout direction. - * @param direction {NbLayoutDirection} direction to set. - * */ + * Sets layout direction + * @param {NbLayoutDirection} direction + */ setDirection(direction: NbLayoutDirection) { this.direction = direction; this.$directionChange.next(direction); From 243a7b6afdce088361cf91e9a77f64e16ca27573 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Mon, 7 May 2018 19:38:29 +0300 Subject: [PATCH 87/89] docs(rtl): use code snippets syntax --- docs/articles/rtl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/articles/rtl.md b/docs/articles/rtl.md index 8b6a62cd10..b2d75c9d33 100644 --- a/docs/articles/rtl.md +++ b/docs/articles/rtl.md @@ -7,7 +7,7 @@ For instance, if we need the sidebar to be positioned logically depending on a l ``` -Document direction could be set through the NbThemeModule.forRoot call. Supported values are 'ltr' and 'rtl'. +Document direction could be set through the `NbThemeModule.forRoot` call. Supported values are `ltr` and `rtl`. ```typescript @NgModule({ From c476b78f1bc49c2ecc24374044450148e74f14c9 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Tue, 8 May 2018 13:28:11 +0300 Subject: [PATCH 88/89] style: fix typo --- docs/articles/rtl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/articles/rtl.md b/docs/articles/rtl.md index b2d75c9d33..21dc26e321 100644 --- a/docs/articles/rtl.md +++ b/docs/articles/rtl.md @@ -21,7 +21,7 @@ Default value is `ltr`.
Note
- Components must be placed inside of the `` component to correctly support language direction. + Components must be placed inside of the `` component to correctly support language direction.
From 78c0487b8d6ee2b86a393961ae26b0b34d1c3975 Mon Sep 17 00:00:00 2001 From: Sergey Andrievskiy Date: Tue, 8 May 2018 13:29:54 +0300 Subject: [PATCH 89/89] docs(rtl): remove duplicate service entry --- docs/structure.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/docs/structure.ts b/docs/structure.ts index eeae0c905e..384c42eb51 100644 --- a/docs/structure.ts +++ b/docs/structure.ts @@ -418,17 +418,6 @@ export const STRUCTURE = [ }, ], }, - { - type: 'page', - name: 'LayoutDirectionService', - children: [ - { - type: 'block', - block: 'component', - source: 'NbLayoutDirectionService', - }, - ], - }, ], }, {