Skip to content
This repository has been archived by the owner on Dec 19, 2024. It is now read-only.

Commit

Permalink
Merge pull request #26 from PolymerElements/positioning
Browse files Browse the repository at this point in the history
Adds a position attribute and bonus fixes
  • Loading branch information
notwaldorf committed Sep 3, 2015
2 parents 62b5ccc + 32016e4 commit 622b1dc
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 20 deletions.
15 changes: 8 additions & 7 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,10 @@ <h4>Anchored to custom elements</h4>
<paper-icon-button id="back" icon="arrow-back" alt="go back"></paper-icon-button>
<paper-icon-button id="fwd" icon="arrow-forward" alt="go forward"></paper-icon-button>

<paper-tooltip for="heart" margin-top="0">&lt;3 &lt;3 &lt;3 </paper-tooltip>
<paper-tooltip for="back" margin-top="0">halp I am trapped in a tooltip</paper-tooltip>
<paper-tooltip for="fwd" margin-top="0">back to the future</paper-tooltip>
<!-- paper-icon-buttons have an inherent padding that will push the tooltip down. offset undoes it -->
<paper-tooltip for="heart" offset="0">&lt;3 &lt;3 &lt;3 </paper-tooltip>
<paper-tooltip for="back" offset="0">halp I am trapped in a tooltip</paper-tooltip>
<paper-tooltip for="fwd" offset="0">back to the future</paper-tooltip>
</div>
</div>
<div>
Expand All @@ -126,19 +127,19 @@ <h4>Rich-text tooltips (not Material Design)</h4>
<div id="green" class="avatar green" tabindex="0"></div>
<div id="orange" class="avatar orange" tabindex="0"></div>

<paper-tooltip for="red" class="custom">
<paper-tooltip for="red" class="custom" position="left">
<img src="http://i.imgur.com/OuUe8Da.jpg">
Rich-text tooltips are doable but against the Material Design spec.
</paper-tooltip>
<paper-tooltip for="blue" class="custom">
<paper-tooltip for="blue" class="custom" position="right">
<img src="http://i.imgur.com/OuUe8Da.jpg">
Rich-text tooltips are doable but against the Material Design spec.
</paper-tooltip>
<paper-tooltip for="green" class="custom">
<paper-tooltip for="green" class="custom" position="top">
<img src="http://i.imgur.com/OuUe8Da.jpg">
Rich-text tooltips are doable but against the Material Design spec.
</paper-tooltip>
<paper-tooltip for="orange" class="custom">
<paper-tooltip for="orange" class="custom" position="bottom">
<img src="http://i.imgur.com/OuUe8Da.jpg">
Rich-text tooltips are doable but against the Material Design spec.
</paper-tooltip>
Expand Down
2 changes: 1 addition & 1 deletion demo/test-button.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</style>

<paper-icon-button id="m" icon="menu" alt="menu"></paper-icon-button>
<paper-tooltip for="m" margin-top="8">hot dogs</paper-tooltip>
<paper-tooltip for="m" offset="8">hot dogs</paper-tooltip>
</template>

<script>
Expand Down
98 changes: 93 additions & 5 deletions paper-tooltip.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
<paper-tooltip for="btn">Tooltip text</paper-tooltip>
</div>
The tooltip can be positioned on the top|bottom|left|right of the anchor using
the `position` attribute. The default position is bottom.
<paper-tooltip for="btn" position="left">Tooltip text</paper-tooltip>
<paper-tooltip for="btn" position="top">Tooltip text</paper-tooltip>
### Styling
The following custom properties and mixins are available for styling:
Expand Down Expand Up @@ -107,10 +113,37 @@
observer: '_forChanged'
},

/**
* Positions the tooltip to the top, right, bottom, left of its content.
*/
position: {
type: String,
value: 'bottom'
},

/**
* If true, no parts of the tooltip will ever be shown offscreen.
*/
fitToVisibleBounds: {
type: Boolean,
value: false
},

/**
* The spacing between the top of the tooltip and the element it is
* anchored to.
*/
offset: {
type: Number,
value: 14
},

/**
* This property is deprecated, but left over so that it doesn't
* break exiting code. Please use `offset` instead. If both `offset` and
* `marginTop` are provided, `marginTop` will be ignored.
* @deprecated since version 1.0.3
*/
marginTop: {
type: Number,
value: 14
Expand Down Expand Up @@ -186,10 +219,13 @@
if (this._showing)
return;

if (Polymer.dom(this).textContent.trim() === '')
return;

this.cancelAnimation();

this.toggleClass('hidden', false, this.$.tooltip);
this._setPosition();
this.updatePosition();
this._showing = true;

this.playAnimation('entry');
Expand All @@ -207,18 +243,70 @@
this._target = this.target;
},

_setPosition: function() {
updatePosition: function() {
if (!this._target)
return;

var offset = this.offset;
// If a marginTop has been provided by the user (pre 1.0.3), use it.
if (this.marginTop != 14 && this.offset == 14)
offset = this.marginTop;

var parentRect = this.offsetParent.getBoundingClientRect();
var targetRect = this._target.getBoundingClientRect();
var thisRect = this.getBoundingClientRect();

var centerOffset = (targetRect.width - thisRect.width) / 2;
var horizontalCenterOffset = (targetRect.width - thisRect.width) / 2;
var verticalCenterOffset = (targetRect.height - thisRect.height) / 2;

var targetLeft = targetRect.left - parentRect.left;
var targetTop = targetRect.top - parentRect.top;

var tooltipLeft, tooltipTop;

switch (this.position) {
case 'top':
tooltipLeft = targetLeft + horizontalCenterOffset;
tooltipTop = targetTop - thisRect.height - offset;
break;
case 'bottom':
tooltipLeft = targetLeft + horizontalCenterOffset;
tooltipTop = targetTop + targetRect.height + offset;
break;
case 'left':
tooltipLeft = targetLeft - thisRect.width - offset;
tooltipTop = targetTop + verticalCenterOffset;
break;
case 'right':
tooltipLeft = targetLeft + targetRect.width + offset;
tooltipTop = targetTop + verticalCenterOffset;
break;
}

// TODO(noms): This should use IronFitBehavior if possible.
if (this.fitToVisibleBounds) {
// Clip the left/right side.
if (tooltipLeft + thisRect.width > window.innerWidth) {
this.style.right = '0px';
this.style.left = 'auto';
} else {
this.style.left = Math.max(0, tooltipLeft) + 'px';
this.style.right = 'auto';
}

// Clip the top/bottom side.
if (tooltipTop + thisRect.height > window.innerHeight) {
this.style.bottom = '0px';
this.style.top = 'auto';
} else {
this.style.top = Math.max(0, tooltipTop) + 'px';
this.style.bottom = 'auto';
}
} else {
this.style.left = tooltipLeft + 'px';
this.style.top = tooltipTop + 'px';
}

this.style.left = targetRect.left - parentRect.left + centerOffset + 'px';
this.style.top = targetRect.top - parentRect.top + targetRect.height + this.marginTop + 'px';
},

_onAnimationFinish: function() {
Expand Down
Loading

0 comments on commit 622b1dc

Please sign in to comment.