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() {
|
RED.popover = (function() {
|
||||||
var deltaSizes = {
|
var deltaSizes = {
|
||||||
"default": {
|
"default": {
|
||||||
top: 10,
|
x: 12,
|
||||||
topTop: 30,
|
y: 12
|
||||||
leftRight: 17,
|
|
||||||
leftLeft: 25,
|
|
||||||
leftBottom: 8,
|
|
||||||
leftTop: 11
|
|
||||||
},
|
},
|
||||||
"small": {
|
"small": {
|
||||||
top: 6,
|
x:8,
|
||||||
topTop: 20,
|
y:8
|
||||||
leftRight: 8,
|
|
||||||
leftLeft: 26,
|
|
||||||
leftBottom: 8,
|
|
||||||
leftTop: 9
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function createPopover(options) {
|
function createPopover(options) {
|
||||||
@ -41,7 +33,9 @@ RED.popover = (function() {
|
|||||||
var delay = options.delay || { show: 750, hide: 50 };
|
var delay = options.delay || { show: 750, hide: 50 };
|
||||||
var autoClose = options.autoClose;
|
var autoClose = options.autoClose;
|
||||||
var width = options.width||"auto";
|
var width = options.width||"auto";
|
||||||
|
var maxWidth = options.maxWidth;
|
||||||
var size = options.size||"default";
|
var size = options.size||"default";
|
||||||
|
var popupOffset = options.offset || 0;
|
||||||
if (!deltaSizes[size]) {
|
if (!deltaSizes[size]) {
|
||||||
throw new Error("Invalid RED.popover size value:",size);
|
throw new Error("Invalid RED.popover size value:",size);
|
||||||
}
|
}
|
||||||
@ -49,6 +43,8 @@ RED.popover = (function() {
|
|||||||
var timer = null;
|
var timer = null;
|
||||||
var active;
|
var active;
|
||||||
var div;
|
var div;
|
||||||
|
var contentDiv;
|
||||||
|
var currentStyle;
|
||||||
|
|
||||||
var openPopup = function(instant) {
|
var openPopup = function(instant) {
|
||||||
if (active) {
|
if (active) {
|
||||||
@ -58,6 +54,10 @@ RED.popover = (function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
div = $('<div class="red-ui-popover"></div>');
|
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") {
|
if (size !== "default") {
|
||||||
div.addClass("red-ui-popover-size-"+size);
|
div.addClass("red-ui-popover-size-"+size);
|
||||||
}
|
}
|
||||||
@ -67,71 +67,23 @@ RED.popover = (function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (typeof result === 'string') {
|
if (typeof result === 'string') {
|
||||||
div.text(result);
|
contentDiv.text(result);
|
||||||
} else {
|
} else {
|
||||||
div.append(result);
|
contentDiv.append(result);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
div.html(content);
|
contentDiv.html(content);
|
||||||
}
|
|
||||||
if (width !== "auto") {
|
|
||||||
div.width(width);
|
|
||||||
}
|
}
|
||||||
div.appendTo("body");
|
div.appendTo("body");
|
||||||
|
|
||||||
var targetPos = target.offset();
|
movePopup({target,direction,width,maxWidth});
|
||||||
var targetWidth = target.outerWidth();
|
|
||||||
var targetHeight = target.outerHeight();
|
|
||||||
var divHeight = div.height();
|
|
||||||
var divWidth = div.width();
|
|
||||||
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;
|
|
||||||
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) {
|
if (existingPopover) {
|
||||||
existingPopover.close(true);
|
existingPopover.close(true);
|
||||||
}
|
}
|
||||||
|
if (options.trigger !== 'manual') {
|
||||||
target.data("red-ui-popover",res)
|
target.data("red-ui-popover",res)
|
||||||
|
}
|
||||||
if (options.tooltip) {
|
if (options.tooltip) {
|
||||||
div.on("mousedown", function(evt) {
|
div.on("mousedown", function(evt) {
|
||||||
closePopup(true);
|
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) {
|
var closePopup = function(instant) {
|
||||||
$(document).off('mousedown.red-ui-popover');
|
$(document).off('mousedown.red-ui-popover');
|
||||||
if (!active) {
|
if (!active) {
|
||||||
@ -236,8 +284,10 @@ RED.popover = (function() {
|
|||||||
},autoClose);
|
},autoClose);
|
||||||
}
|
}
|
||||||
var res = {
|
var res = {
|
||||||
|
get element() { return div },
|
||||||
setContent: function(_content) {
|
setContent: function(_content) {
|
||||||
content = _content;
|
content = _content;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
open: function (instant) {
|
open: function (instant) {
|
||||||
@ -249,6 +299,10 @@ RED.popover = (function() {
|
|||||||
active = false;
|
active = false;
|
||||||
closePopup(instant);
|
closePopup(instant);
|
||||||
return res;
|
return res;
|
||||||
|
},
|
||||||
|
move: function(options) {
|
||||||
|
movePopup(options);
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -140,8 +140,8 @@ $workspace-button-color-focus-outline: $form-input-focus-color;
|
|||||||
|
|
||||||
$shade-color: rgba(160,160,160,0.5);
|
$shade-color: rgba(160,160,160,0.5);
|
||||||
|
|
||||||
|
|
||||||
$popover-background: #333;
|
$popover-background: #333;
|
||||||
|
$popover-border: $popover-background;
|
||||||
$popover-color: #eee;
|
$popover-color: #eee;
|
||||||
$popover-button-border-color: #bbb;
|
$popover-button-border-color: #bbb;
|
||||||
$popover-button-border-color-hover: #666;
|
$popover-button-border-color-hover: #666;
|
||||||
|
@ -19,19 +19,23 @@
|
|||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: auto;
|
width: auto;
|
||||||
padding: 10px;
|
padding: 2px;
|
||||||
height: auto;
|
height: auto;
|
||||||
background: $popover-background;
|
background: var(--red-ui-popover-border);
|
||||||
color: $popover-color;
|
color: var(--red-ui-popover-color);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
font-family: $primary-font;
|
font-family: $primary-font;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
@include component-shadow;
|
@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 {
|
.red-ui-popover:after, .red-ui-popover:before {
|
||||||
border: solid transparent;
|
border: solid transparent;
|
||||||
content: " ";
|
content: " ";
|
||||||
@ -61,26 +65,26 @@
|
|||||||
|
|
||||||
.red-ui-popover.red-ui-popover-right:after {
|
.red-ui-popover.red-ui-popover-right:after {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
border-right-color: $popover-background;
|
border-right-color: var(--red-ui-popover-border);
|
||||||
border-width: 10px;
|
border-width: 10px;
|
||||||
margin-top: -10px;
|
margin-top: -10px;
|
||||||
}
|
}
|
||||||
.red-ui-popover.red-ui-popover-right:before {
|
.red-ui-popover.red-ui-popover-right:before {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
border-right-color: $popover-background;
|
border-right-color: var(--red-ui-popover-border);
|
||||||
border-width: 11px;
|
border-width: 11px;
|
||||||
margin-top: -11px;
|
margin-top: -11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-ui-popover.red-ui-popover-left:after {
|
.red-ui-popover.red-ui-popover-left:after {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
border-left-color: $popover-background;
|
border-left-color: var(--red-ui-popover-border);
|
||||||
border-width: 10px;
|
border-width: 10px;
|
||||||
margin-top: -10px;
|
margin-top: -10px;
|
||||||
}
|
}
|
||||||
.red-ui-popover.red-ui-popover-left:before {
|
.red-ui-popover.red-ui-popover-left:before {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
border-left-color: $popover-background;
|
border-left-color: var(--red-ui-popover-border);
|
||||||
border-width: 11px;
|
border-width: 11px;
|
||||||
margin-top: -11px;
|
margin-top: -11px;
|
||||||
}
|
}
|
||||||
@ -88,26 +92,26 @@
|
|||||||
|
|
||||||
.red-ui-popover.red-ui-popover-bottom:after {
|
.red-ui-popover.red-ui-popover-bottom:after {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
border-bottom-color: $popover-background;
|
border-bottom-color: var(--red-ui-popover-border);
|
||||||
border-width: 10px;
|
border-width: 10px;
|
||||||
margin-left: -10px;
|
margin-left: -10px;
|
||||||
}
|
}
|
||||||
.red-ui-popover.red-ui-popover-bottom:before {
|
.red-ui-popover.red-ui-popover-bottom:before {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
border-bottom-color: $popover-background;
|
border-bottom-color: var(--red-ui-popover-border);
|
||||||
border-width: 11px;
|
border-width: 11px;
|
||||||
margin-left: -11px;
|
margin-left: -11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-ui-popover.red-ui-popover-top:after {
|
.red-ui-popover.red-ui-popover-top:after {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
border-top-color: $popover-background;
|
border-top-color: var(--red-ui-popover-border);
|
||||||
border-width: 10px;
|
border-width: 10px;
|
||||||
margin-left: -10px;
|
margin-left: -10px;
|
||||||
}
|
}
|
||||||
.red-ui-popover.red-ui-popover-top:before {
|
.red-ui-popover.red-ui-popover-top:before {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
border-top-color: $popover-background;
|
border-top-color: var(--red-ui-popover-border);
|
||||||
border-width: 11px;
|
border-width: 11px;
|
||||||
margin-left: -11px;
|
margin-left: -11px;
|
||||||
}
|
}
|
||||||
@ -116,9 +120,10 @@
|
|||||||
|
|
||||||
.red-ui-popover-size-small {
|
.red-ui-popover-size-small {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 5px 7px;
|
|
||||||
line-height: 1.8em;
|
line-height: 1.8em;
|
||||||
|
.red-ui-popover-content {
|
||||||
|
padding: 1px 4px;
|
||||||
|
}
|
||||||
&.red-ui-popover-right:after, &.red-ui-popover-left:after {
|
&.red-ui-popover-right:after, &.red-ui-popover-left:after {
|
||||||
border-width: 7px;
|
border-width: 7px;
|
||||||
margin-top: -7px;
|
margin-top: -7px;
|
||||||
@ -143,7 +148,7 @@
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-family: $monospace-font;
|
font-family: $monospace-font;
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
border: 1px solid $popover-color;
|
border: 1px solid var(--red-ui-popover-color);
|
||||||
border-radius:3px;
|
border-radius:3px;
|
||||||
padding: 1px 2px;
|
padding: 1px 2px;
|
||||||
}
|
}
|
||||||
@ -152,8 +157,8 @@
|
|||||||
.red-ui-popover button.red-ui-button {
|
.red-ui-popover button.red-ui-button {
|
||||||
&:not(.primary) {
|
&:not(.primary) {
|
||||||
border-color: $popover-button-border-color;
|
border-color: $popover-button-border-color;
|
||||||
background: $popover-background;
|
background: var(--red-ui-popover-background);
|
||||||
color: $popover-color !important;
|
color: var(--red-ui-popover-color) !important;
|
||||||
}
|
}
|
||||||
&:not(.primary):not(.disabled):not(.ui-button-disabled):hover {
|
&:not(.primary):not(.disabled):not(.ui-button-disabled):hover {
|
||||||
border-color: $popover-button-border-color-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-border: #{$node-status-changed-border};
|
||||||
--red-ui-node-status-changed-background: #{$node-status-changed-background};
|
--red-ui-node-status-changed-background: #{$node-status-changed-background};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--red-ui-node-border: #{$node-border};
|
--red-ui-node-border: #{$node-border};
|
||||||
--red-ui-node-port-background:#{$node-port-background};
|
--red-ui-node-port-background:#{$node-port-background};
|
||||||
|
|
||||||
--red-ui-node-label-color: #{$node-label-color};
|
--red-ui-node-label-color: #{$node-label-color};
|
||||||
--red-ui-node-selected-color: #{$node-selected-color};
|
--red-ui-node-selected-color: #{$node-selected-color};
|
||||||
--red-ui-port-selected-color: #{$port-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