From ccea85012e9f262dc2feb0e3b8018eadd2f5ed09 Mon Sep 17 00:00:00 2001
From: Vitaliy Makogon
Date: Thu, 25 Apr 2019 15:31:20 +0300
Subject: [PATCH] feat(popover,tooltip): add adaptivePosition option to disable
adaptive positioning
---
.../adaptive-position/adaptive-position.html | 15 +++++++
.../adaptive-position/adaptive-position.ts | 7 ++++
.../app/components/+popover/demos/index.ts | 40 ++++++++++---------
.../+popover/popover-section.list.ts | 39 +++++++++---------
.../adaptive-position/adaptive-position.html | 13 ++++++
.../adaptive-position/adaptive-position.ts | 7 ++++
.../app/components/+tooltip/demos/index.ts | 30 +++++++-------
.../+tooltip/tooltip-section.list.ts | 26 ++++++++----
.../adaptive-position/adaptive-position.html | 2 +-
src/popover/popover.config.ts | 2 +
src/popover/popover.directive.ts | 23 +++++++----
src/positioning/models/index.ts | 3 ++
src/positioning/modifiers/preventOverflow.ts | 6 ++-
src/tooltip/tooltip.config.ts | 2 +
src/tooltip/tooltip.directive.ts | 13 ++++++
15 files changed, 159 insertions(+), 69 deletions(-)
create mode 100644 demo/src/app/components/+popover/demos/adaptive-position/adaptive-position.html
create mode 100644 demo/src/app/components/+popover/demos/adaptive-position/adaptive-position.ts
create mode 100644 demo/src/app/components/+tooltip/demos/adaptive-position/adaptive-position.html
create mode 100644 demo/src/app/components/+tooltip/demos/adaptive-position/adaptive-position.ts
diff --git a/demo/src/app/components/+popover/demos/adaptive-position/adaptive-position.html b/demo/src/app/components/+popover/demos/adaptive-position/adaptive-position.html
new file mode 100644
index 0000000000..b7f6e20a93
--- /dev/null
+++ b/demo/src/app/components/+popover/demos/adaptive-position/adaptive-position.html
@@ -0,0 +1,15 @@
+
+
+
\ No newline at end of file
diff --git a/demo/src/app/components/+popover/demos/adaptive-position/adaptive-position.ts b/demo/src/app/components/+popover/demos/adaptive-position/adaptive-position.ts
new file mode 100644
index 0000000000..5024cb5467
--- /dev/null
+++ b/demo/src/app/components/+popover/demos/adaptive-position/adaptive-position.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'demo-popover-adaptive-position',
+ templateUrl: './adaptive-position.html'
+})
+export class DemoPopoverAdaptivePositionComponent {}
diff --git a/demo/src/app/components/+popover/demos/index.ts b/demo/src/app/components/+popover/demos/index.ts
index 055df889ba..304265f714 100644
--- a/demo/src/app/components/+popover/demos/index.ts
+++ b/demo/src/app/components/+popover/demos/index.ts
@@ -1,37 +1,39 @@
+import { DemoPopoverAdaptivePositionComponent } from './adaptive-position/adaptive-position';
import { DemoPopoverBasicComponent } from './basic/basic';
-import { DemoPopoverPlacementComponent } from './placement/placement';
+import { DemoPopoverByIsOpenPropComponent } from './trigger-by-isopen-property/trigger-by-isopen-property';
+import { DemoPopoverClassComponent } from './class/class';
+import { DemoPopoverConfigComponent } from './config/config';
+import { DemoPopoverContainerComponent } from './container/container';
+import { DemoPopoverContextComponent } from './popover-context/popover-context';
+import { DemoPopoverCustomContentComponent } from './custom-content/custom-content';
import { DemoPopoverDismissComponent } from './dismiss/dismiss';
import { DemoPopoverDynamicComponent } from './dynamic/dynamic';
-import { DemoPopoverCustomContentComponent } from './custom-content/custom-content';
import { DemoPopoverDynamicHtmlComponent } from './dynamic-html/dynamic-html';
-import { DemoPopoverContainerComponent } from './container/container';
-import { DemoPopoverConfigComponent } from './config/config';
+import { DemoPopoverEventsComponent } from './events/events';
+import { DemoPopoverOutsideClickComponent } from './outside-click/outside-click';
+import { DemoPopoverPlacementComponent } from './placement/placement';
import { DemoPopoverStylingGlobalComponent } from './styling-global/styling-global';
import { DemoPopoverStylingLocalComponent } from './styling-local/styling-local';
import { DemoPopoverTriggersCustomComponent } from './triggers-custom/triggers-custom';
import { DemoPopoverTriggersManualComponent } from './triggers-manual/triggers-manual';
-import { DemoPopoverByIsOpenPropComponent } from './trigger-by-isopen-property/trigger-by-isopen-property';
-import { DemoPopoverClassComponent } from './class/class';
-import { DemoPopoverOutsideClickComponent } from './outside-click/outside-click';
-import { DemoPopoverEventsComponent } from './events/events';
-import { DemoPopoverContextComponent } from './popover-context/popover-context';
export const DEMO_COMPONENTS = [
+ DemoPopoverAdaptivePositionComponent,
DemoPopoverBasicComponent,
- DemoPopoverPlacementComponent,
+ DemoPopoverByIsOpenPropComponent,
+ DemoPopoverClassComponent,
+ DemoPopoverConfigComponent,
+ DemoPopoverContainerComponent,
+ DemoPopoverContextComponent,
+ DemoPopoverCustomContentComponent,
DemoPopoverDismissComponent,
DemoPopoverDynamicComponent,
- DemoPopoverCustomContentComponent,
DemoPopoverDynamicHtmlComponent,
- DemoPopoverContainerComponent,
- DemoPopoverConfigComponent,
+ DemoPopoverEventsComponent,
+ DemoPopoverOutsideClickComponent,
+ DemoPopoverPlacementComponent,
DemoPopoverStylingGlobalComponent,
DemoPopoverStylingLocalComponent,
DemoPopoverTriggersCustomComponent,
- DemoPopoverTriggersManualComponent,
- DemoPopoverByIsOpenPropComponent,
- DemoPopoverClassComponent,
- DemoPopoverOutsideClickComponent,
- DemoPopoverEventsComponent,
- DemoPopoverContextComponent
+ DemoPopoverTriggersManualComponent
];
diff --git a/demo/src/app/components/+popover/popover-section.list.ts b/demo/src/app/components/+popover/popover-section.list.ts
index da17c2e6a7..39874cb210 100644
--- a/demo/src/app/components/+popover/popover-section.list.ts
+++ b/demo/src/app/components/+popover/popover-section.list.ts
@@ -1,20 +1,20 @@
+import { DemoPopoverAdaptivePositionComponent } from './demos/adaptive-position/adaptive-position';
import { DemoPopoverBasicComponent } from './demos/basic/basic';
-import { DemoPopoverPlacementComponent } from './demos/placement/placement';
+import { DemoPopoverByIsOpenPropComponent } from './demos/trigger-by-isopen-property/trigger-by-isopen-property';
+import { DemoPopoverClassComponent } from './demos/class/class';
+import { DemoPopoverConfigComponent } from './demos/config/config';
+import { DemoPopoverContainerComponent } from './demos/container/container';
+import { DemoPopoverContextComponent } from './demos/popover-context/popover-context';
+import { DemoPopoverCustomContentComponent } from './demos/custom-content/custom-content';
import { DemoPopoverDismissComponent } from './demos/dismiss/dismiss';
import { DemoPopoverDynamicComponent } from './demos/dynamic/dynamic';
-import { DemoPopoverCustomContentComponent } from './demos/custom-content/custom-content';
import { DemoPopoverDynamicHtmlComponent } from './demos/dynamic-html/dynamic-html';
-import { DemoPopoverContainerComponent } from './demos/container/container';
-import { DemoPopoverConfigComponent } from './demos/config/config';
+import { DemoPopoverEventsComponent } from './demos/events/events';
import { DemoPopoverOutsideClickComponent } from './demos/outside-click/outside-click';
+import { DemoPopoverPlacementComponent } from './demos/placement/placement';
+import { DemoPopoverStylingLocalComponent } from './demos/styling-local/styling-local';
import { DemoPopoverTriggersCustomComponent } from './demos/triggers-custom/triggers-custom';
import { DemoPopoverTriggersManualComponent } from './demos/triggers-manual/triggers-manual';
-import { DemoPopoverByIsOpenPropComponent } from './demos/trigger-by-isopen-property/trigger-by-isopen-property';
-import { DemoPopoverStylingLocalComponent } from './demos/styling-local/styling-local';
-import { DemoPopoverClassComponent } from './demos/class/class';
-import { DemoPopoverContextComponent } from './demos/popover-context/popover-context';
-import { DemoPopoverStylingGlobalComponent } from './demos/styling-global/styling-global';
-import { DemoPopoverEventsComponent } from './demos/events/events';
import { ContentSection } from '../../docs/models/content-section.model';
import { DemoTopSectionComponent } from '../../docs/demo-section-components/demo-top-section/index';
@@ -57,6 +57,16 @@ export const demoComponentContent: ContentSection[] = [
Besides that, auto
option may be used to detect a position that fits the component on screen.
`,
outlet: DemoPopoverPlacementComponent
},
+ {
+ title: 'Disable adaptive position',
+ anchor: 'adaptive-position',
+ description: `
+ You can disable adaptive position via adaptivePosition
input or config option
+ `,
+ component: require('!!raw-loader?lang=typescript!./demos/adaptive-position/adaptive-position.ts'),
+ html: require('!!raw-loader?lang=markup!./demos/adaptive-position/adaptive-position.html'),
+ outlet: DemoPopoverAdaptivePositionComponent
+ },
{
title: 'Dismiss on next click',
anchor: 'popover-dismiss',
@@ -167,14 +177,7 @@ export const demoComponentContent: ContentSection[] = [
component: require('!!raw-loader?lang=typescript!./demos/popover-context/popover-context.ts'),
html: require('!!raw-loader?lang=markup!./demos/popover-context/popover-context.html'),
outlet: DemoPopoverContextComponent
- }/*,
- {
- title: 'Global styling',
- anchor: 'styling-global',
- component: require('!!raw-loader?lang=typescript!./demos/styling-global/styling-global.ts'),
- html: require('!!raw-loader?lang=markup!./demos/styling-global/styling-global.html'),
- outlet: DemoPopoverStylingGlobalComponent
- }*/
+ }
]
},
{
diff --git a/demo/src/app/components/+tooltip/demos/adaptive-position/adaptive-position.html b/demo/src/app/components/+tooltip/demos/adaptive-position/adaptive-position.html
new file mode 100644
index 0000000000..ceae1cdc59
--- /dev/null
+++ b/demo/src/app/components/+tooltip/demos/adaptive-position/adaptive-position.html
@@ -0,0 +1,13 @@
+
+
+
\ No newline at end of file
diff --git a/demo/src/app/components/+tooltip/demos/adaptive-position/adaptive-position.ts b/demo/src/app/components/+tooltip/demos/adaptive-position/adaptive-position.ts
new file mode 100644
index 0000000000..83619fe5ac
--- /dev/null
+++ b/demo/src/app/components/+tooltip/demos/adaptive-position/adaptive-position.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'demo-tooltip-adaptive-position',
+ templateUrl: './adaptive-position.html'
+})
+export class DemoTooltipAdaptivePositionComponent {}
diff --git a/demo/src/app/components/+tooltip/demos/index.ts b/demo/src/app/components/+tooltip/demos/index.ts
index b066405a7f..a8d1444300 100644
--- a/demo/src/app/components/+tooltip/demos/index.ts
+++ b/demo/src/app/components/+tooltip/demos/index.ts
@@ -1,31 +1,33 @@
+import { DemoTooltipAdaptivePositionComponent } from './adaptive-position/adaptive-position';
import { DemoTooltipBasicComponent } from './basic/basic';
-import { DemoTooltipPlacementComponent } from './placement/placement';
-import { DemoTooltipDismissComponent } from './dismiss/dismiss';
-import { DemoTooltipDynamicComponent } from './dynamic/dynamic';
+import { DemoTooltipClassComponent } from './class/class';
import { DemoTooltipConfigComponent } from './config/config';
import { DemoTooltipContainerComponent } from './container/container';
+import { DemoTooltipCustomContentComponent } from './custom-content/custom-content';
+import { DemoTooltipDelayComponent } from './delay/delay';
+import { DemoTooltipDismissComponent } from './dismiss/dismiss';
+import { DemoTooltipDynamicComponent } from './dynamic/dynamic';
+import { DemoTooltipDynamicHtmlComponent } from './dynamic-html/dynamic-html';
+import { DemoTooltipPlacementComponent } from './placement/placement';
import { DemoTooltipStylingGlobalComponent } from './styling-global/styling-global';
import { DemoTooltipStylingLocalComponent } from './styling-local/styling-local';
import { DemoTooltipTriggersCustomComponent } from './triggers-custom/triggers-custom';
import { DemoTooltipTriggersManualComponent } from './triggers-manual/triggers-manual';
-import { DemoTooltipDynamicHtmlComponent } from './dynamic-html/dynamic-html';
-import { DemoTooltipClassComponent } from './class/class';
-import { DemoTooltipDelayComponent } from './delay/delay';
-import { DemoTooltipCustomContentComponent } from './custom-content/custom-content';
export const DEMO_COMPONENTS = [
+ DemoTooltipAdaptivePositionComponent,
DemoTooltipBasicComponent,
- DemoTooltipPlacementComponent,
- DemoTooltipDismissComponent,
+ DemoTooltipClassComponent,
+ DemoTooltipConfigComponent,
+ DemoTooltipContainerComponent,
DemoTooltipCustomContentComponent,
+ DemoTooltipDelayComponent,
+ DemoTooltipDismissComponent,
DemoTooltipDynamicComponent,
DemoTooltipDynamicHtmlComponent,
- DemoTooltipContainerComponent,
- DemoTooltipConfigComponent,
+ DemoTooltipPlacementComponent,
DemoTooltipStylingGlobalComponent,
DemoTooltipStylingLocalComponent,
DemoTooltipTriggersCustomComponent,
- DemoTooltipTriggersManualComponent,
- DemoTooltipClassComponent,
- DemoTooltipDelayComponent
+ DemoTooltipTriggersManualComponent
];
diff --git a/demo/src/app/components/+tooltip/tooltip-section.list.ts b/demo/src/app/components/+tooltip/tooltip-section.list.ts
index 223bff5a38..1dc316c5e7 100644
--- a/demo/src/app/components/+tooltip/tooltip-section.list.ts
+++ b/demo/src/app/components/+tooltip/tooltip-section.list.ts
@@ -1,15 +1,17 @@
+import { DemoTooltipAdaptivePositionComponent } from './demos/adaptive-position/adaptive-position';
import { DemoTooltipBasicComponent } from './demos/basic/basic';
-import { DemoTooltipPlacementComponent } from './demos/placement/placement';
+import { DemoTooltipClassComponent } from './demos/class/class';
+import { DemoTooltipConfigComponent } from './demos/config/config';
+import { DemoTooltipContainerComponent } from './demos/container/container';
+import { DemoTooltipCustomContentComponent } from './demos/custom-content/custom-content';
+import { DemoTooltipDelayComponent } from './demos/delay/delay';
import { DemoTooltipDismissComponent } from './demos/dismiss/dismiss';
import { DemoTooltipDynamicComponent } from './demos/dynamic/dynamic';
import { DemoTooltipDynamicHtmlComponent } from './demos/dynamic-html/dynamic-html';
-import { DemoTooltipContainerComponent } from './demos/container/container';
-import { DemoTooltipConfigComponent } from './demos/config/config';
+import { DemoTooltipPlacementComponent } from './demos/placement/placement';
+import { DemoTooltipStylingLocalComponent } from './demos/styling-local/styling-local';
import { DemoTooltipTriggersCustomComponent } from './demos/triggers-custom/triggers-custom';
import { DemoTooltipTriggersManualComponent } from './demos/triggers-manual/triggers-manual';
-import { DemoTooltipStylingLocalComponent } from './demos/styling-local/styling-local';
-import { DemoTooltipClassComponent } from './demos/class/class';
-import { DemoTooltipStylingGlobalComponent } from './demos/styling-global/styling-global';
import { ContentSection } from '../../docs/models/content-section.model';
import { DemoTopSectionComponent } from '../../docs/demo-section-components/demo-top-section/index';
@@ -20,8 +22,6 @@ import {
NgApiDocComponent,
NgApiDocConfigComponent
} from '../../docs/api-docs';
-import { DemoTooltipDelayComponent } from './demos/delay/delay';
-import { DemoTooltipCustomContentComponent } from './demos/custom-content/custom-content';
export const demoComponentContent: ContentSection[] = [
{
@@ -54,6 +54,16 @@ export const demoComponentContent: ContentSection[] = [
used to detect a position that fits the component on the screen.`,
outlet: DemoTooltipPlacementComponent
},
+ {
+ title: 'Disable adaptive position',
+ anchor: 'adaptive-position',
+ description: `
+ You can disable adaptive position via adaptivePosition
input or config option
+ `,
+ component: require('!!raw-loader?lang=typescript!./demos/adaptive-position/adaptive-position.ts'),
+ html: require('!!raw-loader?lang=markup!./demos/adaptive-position/adaptive-position.html'),
+ outlet: DemoTooltipAdaptivePositionComponent
+ },
{
title: 'Dismiss on next click',
anchor: 'dismiss',
diff --git a/demo/src/app/components/+typeahead/demos/adaptive-position/adaptive-position.html b/demo/src/app/components/+typeahead/demos/adaptive-position/adaptive-position.html
index 4cc790c992..168adb1690 100644
--- a/demo/src/app/components/+typeahead/demos/adaptive-position/adaptive-position.html
+++ b/demo/src/app/components/+typeahead/demos/adaptive-position/adaptive-position.html
@@ -1,5 +1,5 @@
\ No newline at end of file
diff --git a/src/popover/popover.config.ts b/src/popover/popover.config.ts
index 6b9d4a19c7..b6435e5c7e 100644
--- a/src/popover/popover.config.ts
+++ b/src/popover/popover.config.ts
@@ -8,6 +8,8 @@ import { Injectable } from '@angular/core';
*/
@Injectable()
export class PopoverConfig {
+ /** sets disable adaptive position */
+ adaptivePosition = true;
/**
* Placement of a popover. Accepts: "top", "bottom", "left", "right", "auto"
*/
diff --git a/src/popover/popover.directive.ts b/src/popover/popover.directive.ts
index 0d2362bd32..bffd2227fe 100644
--- a/src/popover/popover.directive.ts
+++ b/src/popover/popover.directive.ts
@@ -12,6 +12,8 @@ import { PositioningService } from 'ngx-bootstrap/positioning';
*/
@Directive({selector: '[popover]', exportAs: 'bs-popover'})
export class PopoverDirective implements OnInit, OnDestroy {
+ /** sets disable adaptive position */
+ @Input() adaptivePosition: boolean;
/**
* Content to be displayed as popover.
*/
@@ -94,7 +96,9 @@ export class PopoverDirective implements OnInit, OnDestroy {
_renderer
)
.provide({provide: PopoverConfig, useValue: _config});
+
Object.assign(this, _config);
+
this.onShown = this._popover.onShown;
this.onHidden = this._popover.onHidden;
@@ -115,6 +119,17 @@ export class PopoverDirective implements OnInit, OnDestroy {
* the popover.
*/
show(): void {
+ this._positionService.setOptions({
+ modifiers: {
+ flip: {
+ enabled: this.adaptivePosition
+ },
+ preventOverflow: {
+ enabled: this.adaptivePosition
+ }
+ }
+ });
+
if (this._popover.isShown || !this.popover) {
return;
}
@@ -165,14 +180,6 @@ export class PopoverDirective implements OnInit, OnDestroy {
}
this._isInited = true;
- this._positionService.setOptions({
- modifiers: {
- flip: {
- enabled: true
- }
- }
- });
-
this._popover.listen({
triggers: this.triggers,
outsideClick: this.outsideClick,
diff --git a/src/positioning/models/index.ts b/src/positioning/models/index.ts
index 4315155a66..ee99ee84d9 100644
--- a/src/positioning/models/index.ts
+++ b/src/positioning/models/index.ts
@@ -32,5 +32,8 @@ export interface Options {
flip?: {
enabled: boolean;
};
+ preventOverflow?: {
+ enabled: boolean;
+ };
};
}
diff --git a/src/positioning/modifiers/preventOverflow.ts b/src/positioning/modifiers/preventOverflow.ts
index 25335bd553..88a851b216 100644
--- a/src/positioning/modifiers/preventOverflow.ts
+++ b/src/positioning/modifiers/preventOverflow.ts
@@ -1,8 +1,12 @@
-import { getBoundaries } from '../utils';
+import { getBoundaries, isModifierEnabled } from '../utils';
import { Data } from '../models';
export function preventOverflow(data: Data) {
+ if (!isModifierEnabled(data.options, 'preventOverflow')) {
+ return data;
+ }
+
// NOTE: DOM access here
// resets the targetOffsets's position so that the document size can be calculated excluding
// the size of the targetOffsets element itself
diff --git a/src/tooltip/tooltip.config.ts b/src/tooltip/tooltip.config.ts
index 3a456745dd..02c4e993ed 100644
--- a/src/tooltip/tooltip.config.ts
+++ b/src/tooltip/tooltip.config.ts
@@ -3,6 +3,8 @@ import { Injectable } from '@angular/core';
/** Default values provider for tooltip */
@Injectable()
export class TooltipConfig {
+ /** sets disable adaptive position */
+ adaptivePosition = true;
/** tooltip placement, supported positions: 'top', 'bottom', 'left', 'right' */
placement = 'top';
/** array of event names which triggers tooltip opening */
diff --git a/src/tooltip/tooltip.directive.ts b/src/tooltip/tooltip.directive.ts
index db8ae51a8e..ecaa9d0dee 100644
--- a/src/tooltip/tooltip.directive.ts
+++ b/src/tooltip/tooltip.directive.ts
@@ -30,6 +30,8 @@ let id = 0;
})
export class TooltipDirective implements OnInit, OnDestroy {
tooltipId = id++;
+ /** sets disable adaptive position */
+ @Input() adaptivePosition: boolean;
/**
* Content to be displayed as tooltip.
*/
@@ -263,6 +265,17 @@ export class TooltipDirective implements OnInit, OnDestroy {
* the tooltip.
*/
show(): void {
+ this._positionService.setOptions({
+ modifiers: {
+ flip: {
+ enabled: this.adaptivePosition
+ },
+ preventOverflow: {
+ enabled: this.adaptivePosition
+ }
+ }
+ });
+
if (
this.isOpen ||
this.isDisabled ||