mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Allow popovers to be moved and styled
This commit is contained in:
parent
228c15ace3
commit
2c456f044f
@ -17,20 +17,12 @@
|
||||
RED.popover = (function() {
|
||||
var deltaSizes = {
|
||||
"default": {
|
||||
top: 10,
|
||||
topTop: 30,
|
||||
leftRight: 17,
|
||||
leftLeft: 25,
|
||||
leftBottom: 8,
|
||||
leftTop: 11
|
||||
x: 12,
|
||||
y: 12
|
||||
},
|
||||
"small": {
|
||||
top: 6,
|
||||
topTop: 20,
|
||||
leftRight: 8,
|
||||
leftLeft: 26,
|
||||
leftBottom: 8,
|
||||
leftTop: 9
|
||||
x:8,
|
||||
y:8
|
||||
}
|
||||
}
|
||||
function createPopover(options) {
|
||||
@ -41,7 +33,9 @@ RED.popover = (function() {
|
||||
var delay = options.delay || { show: 750, hide: 50 };
|
||||
var autoClose = options.autoClose;
|
||||
var width = options.width||"auto";
|
||||
var maxWidth = options.maxWidth;
|
||||
var size = options.size||"default";
|
||||
var popupOffset = options.offset || 0;
|
||||
if (!deltaSizes[size]) {
|
||||
throw new Error("Invalid RED.popover size value:",size);
|
||||
}
|
||||
@ -49,6 +43,8 @@ RED.popover = (function() {
|
||||
var timer = null;
|
||||
var active;
|
||||
var div;
|
||||
var contentDiv;
|
||||
var currentStyle;
|
||||
|
||||
var openPopup = function(instant) {
|
||||
if (active) {
|
||||
@ -58,6 +54,10 @@ RED.popover = (function() {
|
||||
return;
|
||||
}
|
||||
div = $('<div class="red-ui-popover"></div>');
|
||||
if (options.class) {
|
||||
div.addClass(options.class);
|
||||
}
|
||||
contentDiv = $('<div class="red-ui-popover-content">').appendTo(div);
|
||||
if (size !== "default") {
|
||||
div.addClass("red-ui-popover-size-"+size);
|
||||
}
|
||||
@ -67,71 +67,23 @@ RED.popover = (function() {
|
||||
return;
|
||||
}
|
||||
if (typeof result === 'string') {
|
||||
div.text(result);
|
||||
contentDiv.text(result);
|
||||
} else {
|
||||
div.append(result);
|
||||
contentDiv.append(result);
|
||||
}
|
||||
} else {
|
||||
div.html(content);
|
||||
}
|
||||
if (width !== "auto") {
|
||||
div.width(width);
|
||||
contentDiv.html(content);
|
||||
}
|
||||
div.appendTo("body");
|
||||
|
||||
var targetPos = target.offset();
|
||||
var targetWidth = target.outerWidth();
|
||||
var targetHeight = target.outerHeight();
|
||||
var divHeight = div.height();
|
||||
var divWidth = div.width();
|
||||
var paddingRight = 10;
|
||||
movePopup({target,direction,width,maxWidth});
|
||||
|
||||
var viewportTop = $(window).scrollTop();
|
||||
var viewportLeft = $(window).scrollLeft();
|
||||
var viewportBottom = viewportTop + $(window).height();
|
||||
var viewportRight = viewportLeft + $(window).width();
|
||||
var top = 0;
|
||||
var left = 0;
|
||||
var d = direction;
|
||||
if (d === 'right') {
|
||||
top = targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top;
|
||||
left = targetPos.left+targetWidth+deltaSizes[size].leftRight;
|
||||
} else if (d === 'left') {
|
||||
top = targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top;
|
||||
left = targetPos.left-deltaSizes[size].leftLeft-divWidth;
|
||||
} else if (d === 'bottom') {
|
||||
top = targetPos.top+targetHeight+deltaSizes[size].top;
|
||||
left = targetPos.left+targetWidth/2-divWidth/2 - deltaSizes[size].leftBottom;
|
||||
if (left < 0) {
|
||||
d = "right";
|
||||
top = targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top;
|
||||
left = targetPos.left+targetWidth+deltaSizes[size].leftRight;
|
||||
} else if (left+divWidth+paddingRight > viewportRight) {
|
||||
d = "left";
|
||||
top = targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top;
|
||||
left = targetPos.left-deltaSizes[size].leftLeft-divWidth;
|
||||
if (top+divHeight+targetHeight/2 + 5 > viewportBottom) {
|
||||
top -= (top+divHeight+targetHeight/2 - viewportBottom + 5)
|
||||
}
|
||||
} else if (top+divHeight > viewportBottom) {
|
||||
d = 'top';
|
||||
top = targetPos.top-deltaSizes[size].topTop-divHeight;
|
||||
left = targetPos.left+targetWidth/2-divWidth/2 - deltaSizes[size].leftTop;
|
||||
}
|
||||
} else if (d === 'top') {
|
||||
top = targetPos.top-deltaSizes[size].topTop-divHeight;
|
||||
left = targetPos.left+targetWidth/2-divWidth/2 - deltaSizes[size].leftTop;
|
||||
if (top < 0) {
|
||||
d = 'bottom';
|
||||
top = targetPos.top+targetHeight+deltaSizes[size].top;
|
||||
left = targetPos.left+targetWidth/2-divWidth/2 - deltaSizes[size].leftBottom;
|
||||
}
|
||||
}
|
||||
div.addClass('red-ui-popover-'+d).css({top: top, left: left});
|
||||
if (existingPopover) {
|
||||
existingPopover.close(true);
|
||||
}
|
||||
if (options.trigger !== 'manual') {
|
||||
target.data("red-ui-popover",res)
|
||||
}
|
||||
if (options.tooltip) {
|
||||
div.on("mousedown", function(evt) {
|
||||
closePopup(true);
|
||||
@ -161,6 +113,102 @@ RED.popover = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
var movePopup = function(options) {
|
||||
target = options.target || target;
|
||||
direction = options.direction || direction || "right";
|
||||
popupOffset = options.offset || popupOffset;
|
||||
var transition = options.transition;
|
||||
|
||||
var width = options.width||"auto";
|
||||
div.width(width);
|
||||
if (options.maxWidth) {
|
||||
div.css("max-width",options.maxWidth)
|
||||
}
|
||||
|
||||
var targetPos = target[0].getBoundingClientRect();
|
||||
var targetHeight = targetPos.height;
|
||||
var targetWidth = targetPos.width;
|
||||
|
||||
var divHeight = div.outerHeight();
|
||||
var divWidth = div.outerWidth();
|
||||
var paddingRight = 10;
|
||||
|
||||
var viewportTop = $(window).scrollTop();
|
||||
var viewportLeft = $(window).scrollLeft();
|
||||
var viewportBottom = viewportTop + $(window).height();
|
||||
var viewportRight = viewportLeft + $(window).width();
|
||||
var top = 0;
|
||||
var left = 0;
|
||||
if (direction === 'right') {
|
||||
top = targetPos.top+targetHeight/2-divHeight/2;
|
||||
left = targetPos.left+targetWidth+deltaSizes[size].x+popupOffset;
|
||||
} else if (direction === 'left') {
|
||||
top = targetPos.top+targetHeight/2-divHeight/2;
|
||||
left = targetPos.left-deltaSizes[size].x-divWidth-popupOffset;
|
||||
} else if (direction === 'bottom') {
|
||||
top = targetPos.top+targetHeight+deltaSizes[size].y+popupOffset;
|
||||
left = targetPos.left+targetWidth/2-divWidth/2;
|
||||
if (left < 0) {
|
||||
direction = "right";
|
||||
top = targetPos.top+targetHeight/2-divHeight/2;
|
||||
left = targetPos.left+targetWidth+deltaSizes[size].x+popupOffset;
|
||||
} else if (left+divWidth+paddingRight > viewportRight) {
|
||||
direction = "left";
|
||||
top = targetPos.top+targetHeight/2-divHeight/2;
|
||||
left = targetPos.left-deltaSizes[size].x-divWidth-popupOffset;
|
||||
if (top+divHeight+targetHeight/2 + 5 > viewportBottom) {
|
||||
top -= (top+divHeight+targetHeight/2 - viewportBottom + 5)
|
||||
}
|
||||
} else if (top+divHeight > viewportBottom) {
|
||||
direction = 'top';
|
||||
top = targetPos.top-deltaSizes[size].y-divHeight-popupOffset;
|
||||
left = targetPos.left+targetWidth/2-divWidth/2;
|
||||
}
|
||||
} else if (direction === 'top') {
|
||||
top = targetPos.top-deltaSizes[size].y-divHeight-popupOffset;
|
||||
left = targetPos.left+targetWidth/2-divWidth/2;
|
||||
if (top < 0) {
|
||||
direction = 'bottom';
|
||||
top = targetPos.top+targetHeight+deltaSizes[size].y+popupOffset;
|
||||
left = targetPos.left+targetWidth/2-divWidth/2;
|
||||
}
|
||||
} else if (/inset/.test(direction)) {
|
||||
top = targetPos.top + targetHeight/2 - divHeight/2;
|
||||
left = targetPos.left + targetWidth/2 - divWidth/2;
|
||||
|
||||
if (/bottom/.test(direction)) {
|
||||
top = targetPos.top + targetHeight - divHeight-popupOffset;
|
||||
}
|
||||
if (/top/.test(direction)) {
|
||||
top = targetPos.top+popupOffset;
|
||||
}
|
||||
if (/left/.test(direction)) {
|
||||
left = targetPos.left+popupOffset;
|
||||
}
|
||||
if (/right/.test(direction)) {
|
||||
left = targetPos.left + targetWidth - divWidth-popupOffset;
|
||||
}
|
||||
}
|
||||
if (currentStyle) {
|
||||
div.removeClass(currentStyle);
|
||||
}
|
||||
if (transition) {
|
||||
div.css({
|
||||
"transition": "0.6s ease",
|
||||
"transition-property": "top,left,right,bottom"
|
||||
})
|
||||
}
|
||||
currentStyle = 'red-ui-popover-'+direction;
|
||||
div.addClass(currentStyle).css({top: top, left: left});
|
||||
if (transition) {
|
||||
setTimeout(function() {
|
||||
div.css({
|
||||
"transition": "none"
|
||||
});
|
||||
},600);
|
||||
}
|
||||
|
||||
}
|
||||
var closePopup = function(instant) {
|
||||
$(document).off('mousedown.red-ui-popover');
|
||||
if (!active) {
|
||||
@ -236,8 +284,10 @@ RED.popover = (function() {
|
||||
},autoClose);
|
||||
}
|
||||
var res = {
|
||||
get element() { return div },
|
||||
setContent: function(_content) {
|
||||
content = _content;
|
||||
|
||||
return res;
|
||||
},
|
||||
open: function (instant) {
|
||||
@ -249,6 +299,10 @@ RED.popover = (function() {
|
||||
active = false;
|
||||
closePopup(instant);
|
||||
return res;
|
||||
},
|
||||
move: function(options) {
|
||||
movePopup(options);
|
||||
return
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
@ -140,8 +140,8 @@ $workspace-button-color-focus-outline: $form-input-focus-color;
|
||||
|
||||
$shade-color: rgba(160,160,160,0.5);
|
||||
|
||||
|
||||
$popover-background: #333;
|
||||
$popover-border: $popover-background;
|
||||
$popover-color: #eee;
|
||||
$popover-button-border-color: #bbb;
|
||||
$popover-button-border-color-hover: #666;
|
||||
|
@ -19,19 +19,23 @@
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: auto;
|
||||
padding: 10px;
|
||||
padding: 2px;
|
||||
height: auto;
|
||||
background: $popover-background;
|
||||
color: $popover-color;
|
||||
background: var(--red-ui-popover-border);
|
||||
color: var(--red-ui-popover-color);
|
||||
border-radius: 4px;
|
||||
z-index: 1000;
|
||||
font-family: $primary-font;
|
||||
font-size: 14px;
|
||||
line-height: 1.4em;
|
||||
@include component-shadow;
|
||||
border-color: $popover-background;
|
||||
border-color: var(--red-ui-popover-border);
|
||||
}
|
||||
.red-ui-popover-content {
|
||||
padding: 8px;
|
||||
border-radius: 2px;
|
||||
background: var(--red-ui-popover-background);
|
||||
}
|
||||
|
||||
.red-ui-popover:after, .red-ui-popover:before {
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
@ -61,26 +65,26 @@
|
||||
|
||||
.red-ui-popover.red-ui-popover-right:after {
|
||||
border-color: transparent;
|
||||
border-right-color: $popover-background;
|
||||
border-right-color: var(--red-ui-popover-border);
|
||||
border-width: 10px;
|
||||
margin-top: -10px;
|
||||
}
|
||||
.red-ui-popover.red-ui-popover-right:before {
|
||||
border-color: transparent;
|
||||
border-right-color: $popover-background;
|
||||
border-right-color: var(--red-ui-popover-border);
|
||||
border-width: 11px;
|
||||
margin-top: -11px;
|
||||
}
|
||||
|
||||
.red-ui-popover.red-ui-popover-left:after {
|
||||
border-color: transparent;
|
||||
border-left-color: $popover-background;
|
||||
border-left-color: var(--red-ui-popover-border);
|
||||
border-width: 10px;
|
||||
margin-top: -10px;
|
||||
}
|
||||
.red-ui-popover.red-ui-popover-left:before {
|
||||
border-color: transparent;
|
||||
border-left-color: $popover-background;
|
||||
border-left-color: var(--red-ui-popover-border);
|
||||
border-width: 11px;
|
||||
margin-top: -11px;
|
||||
}
|
||||
@ -88,26 +92,26 @@
|
||||
|
||||
.red-ui-popover.red-ui-popover-bottom:after {
|
||||
border-color: transparent;
|
||||
border-bottom-color: $popover-background;
|
||||
border-bottom-color: var(--red-ui-popover-border);
|
||||
border-width: 10px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
.red-ui-popover.red-ui-popover-bottom:before {
|
||||
border-color: transparent;
|
||||
border-bottom-color: $popover-background;
|
||||
border-bottom-color: var(--red-ui-popover-border);
|
||||
border-width: 11px;
|
||||
margin-left: -11px;
|
||||
}
|
||||
|
||||
.red-ui-popover.red-ui-popover-top:after {
|
||||
border-color: transparent;
|
||||
border-top-color: $popover-background;
|
||||
border-top-color: var(--red-ui-popover-border);
|
||||
border-width: 10px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
.red-ui-popover.red-ui-popover-top:before {
|
||||
border-color: transparent;
|
||||
border-top-color: $popover-background;
|
||||
border-top-color: var(--red-ui-popover-border);
|
||||
border-width: 11px;
|
||||
margin-left: -11px;
|
||||
}
|
||||
@ -116,9 +120,10 @@
|
||||
|
||||
.red-ui-popover-size-small {
|
||||
font-size: 12px;
|
||||
padding: 5px 7px;
|
||||
line-height: 1.8em;
|
||||
|
||||
.red-ui-popover-content {
|
||||
padding: 1px 4px;
|
||||
}
|
||||
&.red-ui-popover-right:after, &.red-ui-popover-left:after {
|
||||
border-width: 7px;
|
||||
margin-top: -7px;
|
||||
@ -143,7 +148,7 @@
|
||||
font-size: 11px;
|
||||
font-family: $monospace-font;
|
||||
margin-left: 3px;
|
||||
border: 1px solid $popover-color;
|
||||
border: 1px solid var(--red-ui-popover-color);
|
||||
border-radius:3px;
|
||||
padding: 1px 2px;
|
||||
}
|
||||
@ -152,8 +157,8 @@
|
||||
.red-ui-popover button.red-ui-button {
|
||||
&:not(.primary) {
|
||||
border-color: $popover-button-border-color;
|
||||
background: $popover-background;
|
||||
color: $popover-color !important;
|
||||
background: var(--red-ui-popover-background);
|
||||
color: var(--red-ui-popover-color) !important;
|
||||
}
|
||||
&:not(.primary):not(.disabled):not(.ui-button-disabled):hover {
|
||||
border-color: $popover-button-border-color-hover;
|
||||
|
@ -81,12 +81,15 @@
|
||||
--red-ui-node-status-changed-border: #{$node-status-changed-border};
|
||||
--red-ui-node-status-changed-background: #{$node-status-changed-background};
|
||||
|
||||
|
||||
|
||||
--red-ui-node-border: #{$node-border};
|
||||
--red-ui-node-port-background:#{$node-port-background};
|
||||
|
||||
--red-ui-node-label-color: #{$node-label-color};
|
||||
--red-ui-node-selected-color: #{$node-selected-color};
|
||||
--red-ui-port-selected-color: #{$port-selected-color};
|
||||
|
||||
--red-ui-popover-background: #{$popover-background};
|
||||
--red-ui-popover-border: #{$popover-border};
|
||||
--red-ui-popover-color: #{$popover-color};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user