Skip to content

Commit

Permalink
feat(popover,tooltip): add adaptivePosition option to disable adaptiv…
Browse files Browse the repository at this point in the history
…e positioning
  • Loading branch information
Domainv committed Apr 25, 2019
1 parent b061629 commit ccea850
Show file tree
Hide file tree
Showing 15 changed files with 159 additions and 69 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<button type="button" class="btn btn-default btn-secondary"
popover="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."
popoverTitle="Popover on top"
[adaptivePosition]="false"
placement="top">
Popover on top
</button>

<button type="button" class="btn btn-default btn-secondary"
popover="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."
popoverTitle="Popover on right"
[adaptivePosition]="false"
placement="right">
Popover on right
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Component } from '@angular/core';

@Component({
selector: 'demo-popover-adaptive-position',
templateUrl: './adaptive-position.html'
})
export class DemoPopoverAdaptivePositionComponent {}
40 changes: 21 additions & 19 deletions demo/src/app/components/+popover/demos/index.ts
Original file line number Diff line number Diff line change
@@ -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
];
39 changes: 21 additions & 18 deletions demo/src/app/components/+popover/popover-section.list.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -57,6 +57,16 @@ export const demoComponentContent: ContentSection[] = [
Besides that, <code>auto</code> option may be used to detect a position that fits the component on screen.</p>`,
outlet: DemoPopoverPlacementComponent
},
{
title: 'Disable adaptive position',
anchor: 'adaptive-position',
description: `
<p>You can disable adaptive position via <code>adaptivePosition</code> input or config option</p>
`,
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',
Expand Down Expand Up @@ -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
}*/
}
]
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<button type="button" class="btn btn-default btn-secondary mb-2"
tooltip="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."
[adaptivePosition]="false"
placement="top">
Tooltip on top
</button>

<button type="button" class="btn btn-default btn-secondary mb-2"
tooltip="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."
[adaptivePosition]="false"
placement="right">
Tooltip on right
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Component } from '@angular/core';

@Component({
selector: 'demo-tooltip-adaptive-position',
templateUrl: './adaptive-position.html'
})
export class DemoTooltipAdaptivePositionComponent {}
30 changes: 16 additions & 14 deletions demo/src/app/components/+tooltip/demos/index.ts
Original file line number Diff line number Diff line change
@@ -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
];
26 changes: 18 additions & 8 deletions demo/src/app/components/+tooltip/tooltip-section.list.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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[] = [
{
Expand Down Expand Up @@ -54,6 +54,16 @@ export const demoComponentContent: ContentSection[] = [
used to detect a position that fits the component on the screen.</p>`,
outlet: DemoTooltipPlacementComponent
},
{
title: 'Disable adaptive position',
anchor: 'adaptive-position',
description: `
<p>You can disable adaptive position via <code>adaptivePosition</code> input or config option</p>
`,
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',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<pre class="card card-block card-header mb-3">Model: {{selected | json}}</pre>
<input [(ngModel)]="selected"
[typeahead]="states"
adaptivePosition="true"
[adaptivePosition]="true"
class="form-control">
2 changes: 2 additions & 0 deletions src/popover/popover.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
*/
Expand Down
23 changes: 15 additions & 8 deletions src/popover/popover.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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;

Expand All @@ -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;
}
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions src/positioning/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@ export interface Options {
flip?: {
enabled: boolean;
};
preventOverflow?: {
enabled: boolean;
};
};
}
6 changes: 5 additions & 1 deletion src/positioning/modifiers/preventOverflow.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/tooltip/tooltip.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
13 changes: 13 additions & 0 deletions src/tooltip/tooltip.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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 ||
Expand Down

0 comments on commit ccea850

Please sign in to comment.