1
0
mirror of https://github.com/ansible/awx.git synced 2024-11-01 16:51:11 +03:00

Add alternative trigger event and position support to popover

This commit is contained in:
gconsidine 2017-07-07 15:56:54 -04:00 committed by Marliana Lara
parent d8384522c2
commit 452950ab61
4 changed files with 87 additions and 31 deletions

View File

@ -1,7 +1,7 @@
<label class="at-InputLabel">
<span ng-if="state.required" class="at-InputLabel-required">*</span>
<span class="at-InputLabel-name">{{::state.label}}</span>
<at-popover state="state"></at-popover>
<at-popover position="right" on="mouseover" state="state"></at-popover>
<span ng-if="state._displayHint" class="at-InputLabel-hint">{{::state._hint}}</span>
<div ng-if="state._displayPromptOnLaunch" class="at-InputLabel-checkbox pull-right">
<label class="at-InputLabel-checkboxLabel">

View File

@ -14,6 +14,12 @@
margin: 0;
}
.at-Popover-icon--defaultCursor {
i > {
cursor: default;
}
}
.at-Popover-container {
visibility: hidden;
opacity: 0;
@ -24,7 +30,7 @@
height: auto;
position: fixed;
z-index: 2000;
margin: 0 0 0 18px;
margin: 0;
border-radius: @at-border-radius;
box-shadow: 0 5px 10px rgba(0,0,0, 0.2);
transition: opacity .15s linear;
@ -36,7 +42,7 @@
position: fixed;
z-index: 1999;
padding: 0;
margin: 8px 0 0 3px;
margin: 0;
}
.at-Popover-title {

View File

@ -1,3 +1,10 @@
const DEFAULT_POSITION = 'right';
const DEFAULT_ACTION = 'click';
const DEFAULT_ICON = 'fa fa-question-circle';
const DEFAULT_ALIGNMENT = 'inline';
const DEFAULT_ARROW_HEIGHT = 16;
const DEFAULT_PADDING = 10;
function atPopoverLink (scope, el, attr, controllers) {
let popoverController = controllers[0];
let container = el[0];
@ -13,13 +20,23 @@ function AtPopoverController () {
let container;
let icon;
let popover;
let scope;
vm.init = (scope, _container_, _icon_, _popover_) => {
vm.init = (_scope_, _container_, _icon_, _popover_) => {
scope = _scope_;
icon = _icon_;
popover = _popover_;
scope.inline = true;
icon.addEventListener('click', vm.createDisplayListener());
scope.state.popover = scope.state.popover || {};
vm.inline = scope.state.popover.inline || DEFAULT_ALIGNMENT;
vm.position = scope.state.popover.position || DEFAULT_POSITION;
vm.icon = scope.state.popover.icon || DEFAULT_ICON;
vm.text = scope.state.popover.text || scope.state.help_text;
vm.title = scope.state.popover.title || scope.state.label;
vm.on = scope.state.popover.on || DEFAULT_ACTION;
icon.addEventListener(vm.on, vm.createDisplayListener());
};
vm.createDismissListener = (createEvent) => {
@ -35,7 +52,7 @@ function AtPopoverController () {
popover.style.visibility = 'hidden';
popover.style.opacity = 0;
window.removeEventListener('click', vm.dismissListener);
window.removeEventListener(vm.on, vm.dismissListener);
window.removeEventListener('resize', vm.dismissListener);
};
};
@ -63,36 +80,69 @@ function AtPopoverController () {
vm.open = true;
let arrow = popover.getElementsByClassName('at-Popover-arrow')[0];
arrow.style.lineHeight = `${DEFAULT_ARROW_HEIGHT}px`;
arrow.children[0].style.lineHeight = `${DEFAULT_ARROW_HEIGHT}px`;
let iPos = icon.getBoundingClientRect();
let pPos = popover.getBoundingClientRect();
let pos = {
icon: icon.getBoundingClientRect(),
popover: popover.getBoundingClientRect(),
windowHeight: window.innerHeight,
};
let wHeight = window.clientHeight;
let pHeight = pPos.height;
pos.cx = Math.floor(pos.icon.left + (pos.icon.width / 2));
pos.cy = Math.floor(pos.icon.top + (pos.icon.height / 2));
let cx = Math.floor(iPos.left + (iPos.width / 2));
let cy = Math.floor(iPos.top + (iPos.height / 2));
arrow.style.top = (iPos.top - iPos.height) + 'px';
arrow.style.left = iPos.right + 'px';
if (cy < (pHeight / 2)) {
popover.style.top = '10px';
} else {
popover.style.top = (cy - pHeight / 2) + 'px';
if (vm.position === 'right') {
vm.displayRight(arrow, pos);
} else if (vm.position === 'top') {
vm.displayTop(arrow, pos);
}
popover.style.left = cx + 'px';
popover.style.visibility = 'visible';
popover.style.opacity = 1;
vm.dismissListener = vm.createDismissListener(event);
window.addEventListener('click', vm.dismissListener);
window.addEventListener(vm.on, vm.dismissListener);
window.addEventListener('resize', vm.dismissListener);
};
};
vm.displayRight = (arrow, pos) => {
let arrowTop = Math.floor((pos.cy - (pos.icon.height / 2)));
let arrowLeft = pos.cx + DEFAULT_PADDING;
let popoverTop;
let popoverLeft = arrowLeft + DEFAULT_PADDING - 1;
if (pos.cy < (pos.popover.height / 2)) {
popoverTop = DEFAULT_PADDING;
} else {
popoverTop = Math.floor((pos.cy - pos.popover.height / 2));
}
arrow.style.top = `${arrowTop}px`;
arrow.style.left = `${arrowLeft}px`;
popover.style.top = `${popoverTop}px`;
popover.style.left = `${popoverLeft}px`;
};
vm.displayTop = (arrow, pos) => {
let arrowTop = pos.icon.top - pos.icon.height;
let arrowLeft = Math.floor(pos.icon.right - pos.icon.width - (arrow.style.width / 2));
let popoverTop = pos.icon.top - pos.popover.height - DEFAULT_PADDING;
let popoverLeft = Math.floor(pos.cx - (pos.popover.width / 2));
arrow.style.top = `${arrowTop}px`;
arrow.style.left = `${arrowLeft}px`;
popover.style.top = `${popoverTop}px`;
popover.style.left = `${popoverLeft}px`;
};
}
function atPopover (pathService) {

View File

@ -1,16 +1,16 @@
<div ng-show="state.help_text"
class="at-Popover"
ng-class="{ 'at-Popover--inline': inline }">
<span class="at-Popover-icon">
<i class="fa fa-question-circle"></i>
<div ng-show="vm.text" class="at-Popover" ng-class="{ 'at-Popover--inline': vm.inline }">
<span class="at-Popover-icon"
ng-class="{'at-Popover-icon--defaultCursor': vm.on === 'mouseover'}">
<i class="fa {{ vm.icon }}"></i>
</span>
<div class="at-Popover-container">
<div class="at-Popover-arrow">
<i class="fa fa-caret-left fa-2x"></i>
<i ng-if="vm.position === 'right'" class="fa fa-caret-left fa-2x"></i>
<i ng-if="vm.position === 'top'" class="fa fa-caret-down fa-2x"></i>
</div>
<div class="at-Popover-content">
<h4 class="at-Popover-title">{{::state.label}}</h4>
<p class="at-Popover-text">{{::state.help_text}}</p>
<h4 class="at-Popover-title">{{ vm.title }}</h4>
<p class="at-Popover-text">{{ vm.text }}</p>
</div>
</div>
</div>