Skip to content

Commit

Permalink
fix(tooltip, popover, context menu): correct physical positions in RTL (
Browse files Browse the repository at this point in the history
  • Loading branch information
evtkhvch committed Nov 25, 2021
1 parent b4813e0 commit 0959935
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
NbTrigger,
NbTriggerStrategy,
NbTriggerStrategyBuilderService,
NbLayoutDirectionService,
} from '@nebular/theme';

@Component({ template: '' })
Expand Down Expand Up @@ -127,6 +128,8 @@ export class MockPositionBuilder {

apply() {}

direction() {}

detach() {}

dispose() {}
Expand Down Expand Up @@ -213,6 +216,7 @@ describe('dynamic-overlay-handler', () => {
const bed = TestBed.configureTestingModule({
declarations: [NbDynamicOverlayMockComponent, NbDynamicOverlayMock2Component],
providers: [
NbLayoutDirectionService,
NbDynamicOverlayHandler,
{ provide: NbDynamicOverlay, useClass: NbMockDynamicOverlay },
{ provide: NbTriggerStrategyBuilderService, useClass: MockTriggerStrategyBuilder },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { ElementRef, Injectable, SimpleChange, Type } from '@angular/core';
import { Subject } from 'rxjs';
import { skip, takeUntil } from 'rxjs/operators';

import { NbTrigger, NbTriggerStrategy, NbTriggerStrategyBuilderService } from '../overlay-trigger';
import {
Expand All @@ -11,6 +13,7 @@ import { NbRenderableContainer } from '../overlay-container';
import { NbOverlayContent } from '../overlay-service';
import { NbDynamicOverlay } from './dynamic-overlay';
import { NbOverlayConfig } from '../mapping';
import { NbLayoutDirectionService } from '../../../../services/direction.service';

export class NbDynamicOverlayChange extends SimpleChange {
constructor(previousValue: any, currentValue: any, firstChange: boolean = false) {
Expand Down Expand Up @@ -42,10 +45,13 @@ export class NbDynamicOverlayHandler {

protected changes: { [key: string]: NbDynamicOverlayChange } = {};

protected destroy$ = new Subject<void>();

constructor(
private positionBuilder: NbPositionBuilderService,
private triggerStrategyBuilder: NbTriggerStrategyBuilderService,
private dynamicOverlayService: NbDynamicOverlay,
private directionService: NbLayoutDirectionService,
) {}

host(host: ElementRef) {
Expand Down Expand Up @@ -174,6 +180,7 @@ export class NbDynamicOverlayHandler {
}
this.disconnect();
this.subscribeOnTriggers(this.dynamicOverlay);
this.subscribeOnDirectionChange();
}

disconnect() {
Expand All @@ -183,6 +190,9 @@ export class NbDynamicOverlayHandler {
}

destroy() {
this.destroy$.next();
this.destroy$.complete();

this.disconnect();
this.clearChanges();
if (this.dynamicOverlay) {
Expand All @@ -195,7 +205,8 @@ export class NbDynamicOverlayHandler {
.connectedTo(this._host)
.position(this._position)
.adjustment(this._adjustment)
.offset(this._offset);
.offset(this._offset)
.direction(this.directionService.getDirection());
}

protected subscribeOnTriggers(dynamicOverlay: NbDynamicOverlay) {
Expand All @@ -209,6 +220,15 @@ export class NbDynamicOverlayHandler {
this.triggerStrategy.hide$.subscribe(() => dynamicOverlay.hide());
}

protected subscribeOnDirectionChange() {
this.directionService
.onDirectionChange()
.pipe(skip(1), takeUntil(this.destroy$))
.subscribe(() => {
this.dynamicOverlay.setPositionStrategy(this.createPositionStrategy());
});
}

protected isContainerRerenderRequired() {
return this.isContentUpdated() || this.isContextUpdated() || this.isPositionStrategyUpdateRequired();
}
Expand Down
42 changes: 10 additions & 32 deletions src/framework/theme/components/cdk/overlay/mapping.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
Directive,
Injectable,
ModuleWithProviders,
NgModule,
TemplateRef,
ViewContainerRef,
} from '@angular/core';
import { Directive, Injectable, ModuleWithProviders, NgModule, TemplateRef, ViewContainerRef } from '@angular/core';
import {
CdkPortal,
CdkPortalOutlet,
Expand All @@ -32,26 +25,21 @@ import {
} from '@angular/cdk/overlay';
import { NbScrollStrategyOptions } from '../adapter/block-scroll-strategy-adapter';


@Directive({ selector: '[nbPortal]' })
export class NbPortalDirective extends CdkPortal {
}
export class NbPortalDirective extends CdkPortal {}

@Directive({ selector: '[nbPortalOutlet]' })
export class NbPortalOutletDirective extends CdkPortalOutlet {
}
export class NbPortalOutletDirective extends CdkPortalOutlet {}

export class NbComponentPortal<T = any> extends ComponentPortal<T> {
}
export class NbComponentPortal<T = any> extends ComponentPortal<T> {}

@Injectable()
export class NbOverlay extends Overlay {
scrollStrategies: NbScrollStrategyOptions;
}

@Injectable()
export class NbOverlayPositionBuilder extends OverlayPositionBuilder {
}
export class NbOverlayPositionBuilder extends OverlayPositionBuilder {}

export class NbTemplatePortal<T = any> extends TemplatePortal<T> {
constructor(template: TemplateRef<T>, viewContainerRef?: ViewContainerRef, context?: T) {
Expand All @@ -60,14 +48,11 @@ export class NbTemplatePortal<T = any> extends TemplatePortal<T> {
}

@Injectable()
export class NbOverlayContainer extends OverlayContainer {
}
export class NbOverlayContainer extends OverlayContainer {}

export class NbFlexibleConnectedPositionStrategy extends FlexibleConnectedPositionStrategy {
}
export class NbFlexibleConnectedPositionStrategy extends FlexibleConnectedPositionStrategy {}

export class NbPortalInjector extends PortalInjector {
}
export class NbPortalInjector extends PortalInjector {}

export type NbPortal<T = any> = Portal<T>;
export type NbOverlayRef = OverlayRef;
Expand All @@ -87,21 +72,14 @@ const CDK_MODULES = [OverlayModule, PortalModule];
* */
@NgModule({
imports: [...CDK_MODULES],
exports: [
...CDK_MODULES,
NbPortalDirective,
NbPortalOutletDirective,
],
exports: [...CDK_MODULES, NbPortalDirective, NbPortalOutletDirective],
declarations: [NbPortalDirective, NbPortalOutletDirective],
})
export class NbCdkMappingModule {
static forRoot(): ModuleWithProviders<NbCdkMappingModule> {
return {
ngModule: NbCdkMappingModule,
providers: [
NbOverlay,
NbOverlayPositionBuilder,
],
providers: [NbOverlay, NbOverlayPositionBuilder],
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
NbPosition,
NbAdjustment,
NbViewportRulerAdapter,
NbLayoutDirectionService,
} from '@nebular/theme';

@Injectable()
Expand Down Expand Up @@ -147,8 +148,12 @@ describe('NbAdjustableConnectedPositionStrategy', () => {

it('should map left position to start', () => {
const withPositionsSpy = spyOn(strategy, 'withPositions').and.callThrough();
const directionChangeService: NbLayoutDirectionService = TestBed.inject(NbLayoutDirectionService);

strategy.position(NbPosition.LEFT).adjustment(NbAdjustment.HORIZONTAL);
strategy
.position(NbPosition.LEFT)
.adjustment(NbAdjustment.HORIZONTAL)
.direction(directionChangeService.getDirection());

const overlayService: NbOverlayService = TestBed.inject(NbOverlayService);
overlayRef = overlayService.create({ positionStrategy: strategy });
Expand All @@ -164,8 +169,12 @@ describe('NbAdjustableConnectedPositionStrategy', () => {

it('should map right position to end', () => {
const withPositionsSpy = spyOn(strategy, 'withPositions').and.callThrough();
const directionChangeService: NbLayoutDirectionService = TestBed.inject(NbLayoutDirectionService);

strategy.position(NbPosition.RIGHT).adjustment(NbAdjustment.HORIZONTAL);
strategy
.position(NbPosition.RIGHT)
.adjustment(NbAdjustment.HORIZONTAL)
.direction(directionChangeService.getDirection());

const overlayService: NbOverlayService = TestBed.inject(NbOverlayService);
overlayRef = overlayService.create({ positionStrategy: strategy });
Expand Down
Loading

0 comments on commit 0959935

Please sign in to comment.