Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit fa17c48

Browse files
committed
feat(tooltip): arrow position
- Move arrow position style overrides to a class instead of inline styles. This will allow for consumers to position the arrow to suit their needs by setting margins on the arrow element. - Optimize when the positionTooltip function calls the positionArrow function. Now the arrow position will only be recalced when the tooltip placement changes. Fixes #5464 Closes #5502
1 parent 6fd4789 commit fa17c48

File tree

3 files changed

+42
-32
lines changed

3 files changed

+42
-32
lines changed

src/position/position.js

+8-9
Original file line numberDiff line numberDiff line change
@@ -476,10 +476,17 @@ angular.module('ui.bootstrap.position', [])
476476
return;
477477
}
478478

479+
var arrowCss = {
480+
top: '',
481+
bottom: '',
482+
left: '',
483+
right: ''
484+
};
485+
479486
placement = this.parsePlacement(placement);
480487
if (placement[1] === 'center') {
481488
// no adjustment necessary - just reset styles
482-
angular.element(arrowElem).css({top: '', bottom: '', right: '', left: '', margin: ''});
489+
angular.element(arrowElem).css(arrowCss);
483490
return;
484491
}
485492

@@ -495,14 +502,6 @@ angular.module('ui.bootstrap.position', [])
495502
borderRadiusProp += '-radius';
496503
var borderRadius = $window.getComputedStyle(isTooltip ? innerElem : elem)[borderRadiusProp];
497504

498-
var arrowCss = {
499-
top: 'auto',
500-
bottom: 'auto',
501-
left: 'auto',
502-
right: 'auto',
503-
margin: 0
504-
};
505-
506505
switch (placement[0]) {
507506
case 'top':
508507
arrowCss.bottom = isTooltip ? '0' : '-' + borderWidth;

src/tooltip/tooltip.css

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[uib-tooltip-popup].tooltip.top-left > .tooltip-arrow,
2+
[uib-tooltip-popup].tooltip.top-right > .tooltip-arrow,
3+
[uib-tooltip-popup].tooltip.bottom-left > .tooltip-arrow,
4+
[uib-tooltip-popup].tooltip.bottom-right > .tooltip-arrow,
5+
[uib-tooltip-popup].tooltip.left-top > .tooltip-arrow,
6+
[uib-tooltip-popup].tooltip.left-bottom > .tooltip-arrow,
7+
[uib-tooltip-popup].tooltip.right-top > .tooltip-arrow,
8+
[uib-tooltip-popup].tooltip.right-bottom > .tooltip-arrow,
9+
[uib-popover-popup].popover.top-left > .arrow,
10+
[uib-popover-popup].popover.top-right > .arrow,
11+
[uib-popover-popup].popover.bottom-left > .arrow,
12+
[uib-popover-popup].popover.bottom-right > .arrow,
13+
[uib-popover-popup].popover.left-top > .arrow,
14+
[uib-popover-popup].popover.left-bottom > .arrow,
15+
[uib-popover-popup].popover.right-top > .arrow,
16+
[uib-popover-popup].popover.right-bottom > .arrow {
17+
top: auto;
18+
bottom: auto;
19+
left: auto;
20+
right: auto;
21+
margin: 0;
22+
}

src/tooltip/tooltip.js

+12-23
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
154154
var isOpenParse = angular.isDefined(attrs[prefix + 'IsOpen']) ? $parse(attrs[prefix + 'IsOpen']) : false;
155155
var contentParse = options.useContentExp ? $parse(attrs[ttType]) : false;
156156
var observers = [];
157+
var lastPlacement;
157158

158159
var positionTooltip = function() {
159160
// check if tooltip exists and is not empty
@@ -168,29 +169,16 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
168169
var ttPosition = $position.positionElements(element, tooltip, ttScope.placement, appendToBody);
169170
tooltip.css({ top: ttPosition.top + 'px', left: ttPosition.left + 'px', visibility: 'visible' });
170171

171-
// If the placement class is prefixed, still need
172-
// to remove the TWBS standard class.
173-
if (options.placementClassPrefix) {
174-
tooltip.removeClass('top bottom left right');
175-
}
172+
if (ttPosition.placement !== lastPlacement) {
173+
tooltip.removeClass(lastPlacement.split('-')[0]);
174+
tooltip.addClass(ttPosition.placement.split('-')[0]);
175+
176+
tooltip.removeClass(options.placementClassPrefix + lastPlacement);
177+
tooltip.addClass(options.placementClassPrefix + ttPosition.placement);
176178

177-
tooltip.removeClass(
178-
options.placementClassPrefix + 'top ' +
179-
options.placementClassPrefix + 'top-left ' +
180-
options.placementClassPrefix + 'top-right ' +
181-
options.placementClassPrefix + 'bottom ' +
182-
options.placementClassPrefix + 'bottom-left ' +
183-
options.placementClassPrefix + 'bottom-right ' +
184-
options.placementClassPrefix + 'left ' +
185-
options.placementClassPrefix + 'left-top ' +
186-
options.placementClassPrefix + 'left-bottom ' +
187-
options.placementClassPrefix + 'right ' +
188-
options.placementClassPrefix + 'right-top ' +
189-
options.placementClassPrefix + 'right-bottom');
190-
191-
var placement = ttPosition.placement.split('-');
192-
tooltip.addClass(placement[0] + ' ' + options.placementClassPrefix + ttPosition.placement);
193-
$position.positionArrow(tooltip, ttPosition.placement);
179+
$position.positionArrow(tooltip, ttPosition.placement);
180+
lastPlacement = ttPosition.placement;
181+
}
194182

195183
positionTimeout = null;
196184
}, 0, false);
@@ -365,6 +353,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
365353

366354
ttScope.popupClass = attrs[prefix + 'Class'];
367355
ttScope.placement = angular.isDefined(attrs[prefix + 'Placement']) ? attrs[prefix + 'Placement'] : options.placement;
356+
lastPlacement = '';
368357

369358
var delay = parseInt(attrs[prefix + 'PopupDelay'], 10);
370359
var closeDelay = parseInt(attrs[prefix + 'PopupCloseDelay'], 10);
@@ -540,7 +529,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
540529
}
541530

542531
appendToBody = angular.isDefined(appendToBodyVal) ? appendToBodyVal : appendToBody;
543-
532+
544533
// Make sure tooltip is destroyed and removed.
545534
scope.$on('$destroy', function onDestroyTooltip() {
546535
unregisterTriggers();

0 commit comments

Comments
 (0)