').css({
"position":"absolute",
- "bottom":$("#red-ui-workspace-footer").height() + 12,
- "right": 16,
+ "bottom": 35,
+ "left": 0,
zIndex: 1
- }).addClass('red-ui-navigator-container').appendTo("#red-ui-workspace").hide();
+ }).addClass('red-ui-navigator-container').appendTo("#red-ui-view-navigator-widget").hide();
navBox = d3.select(navContainer[0])
.append("svg:svg")
.attr("width", nav_width)
@@ -169,6 +176,7 @@ RED.view.navigator = (function() {
navBorder.attr('x',newX).attr('y',newY);
$("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor);
$("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor);
+ RED.events.emit("view:navigate");
}).on("mouseup", function() {
isDragging = false;
}).on("mouseenter", function () {
@@ -183,11 +191,7 @@ RED.view.navigator = (function() {
}
})
navBorder = navBox.append("rect").attr("class","red-ui-navigator-border")
- RED.statusBar.add({
- id: "view-navigator",
- align: "right",
- element: $('')
- })
+
$("#red-ui-view-navigate").on("click", function(evt) {
evt.preventDefault();
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js
index 937dd28de..63a93787d 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js
@@ -738,6 +738,7 @@ RED.view = (function() {
chart.scrollLeft(0);
chart.scrollTop(0);
}
+ RED.events.emit("view:navigate");
var scrollDeltaLeft = chart.scrollLeft() - scrollStartLeft;
var scrollDeltaTop = chart.scrollTop() - scrollStartTop;
if (mouse_position != null) {
@@ -765,42 +766,6 @@ RED.view = (function() {
}
})
- RED.statusBar.add({
- id: "view-zoom-controls",
- align: "right",
- element: $('
'+
- ''+
- ''+
- ''+
- ''+
- '')
- })
-
- $("#red-ui-view-zoom-out").on("click", function() { zoomOut(); });
- RED.popover.tooltip($("#red-ui-view-zoom-out"),RED._('actions.zoom-out'),'core:zoom-out');
- $("#red-ui-view-zoom-zero").on("click", zoomZero);
- RED.popover.tooltip($("#red-ui-view-zoom-zero"),RED._('actions.zoom-reset'),'core:zoom-reset');
- $("#red-ui-view-zoom-in").on("click", function() { zoomIn(); });
- RED.popover.tooltip($("#red-ui-view-zoom-in"),RED._('actions.zoom-in'),'core:zoom-in');
- $("#red-ui-view-zoom-fit").on("click", zoomToFitAll);
- RED.popover.tooltip($("#red-ui-view-zoom-fit"),RED._('actions.zoom-fit'),'core:zoom-fit');
- // Legacy mouse wheel handler - disabled in favor of modern wheel event
- // chart.on("DOMMouseScroll mousewheel", function (evt) {
- // if ( evt.altKey || spacebarPressed ) {
- // evt.preventDefault();
- // evt.stopPropagation();
- // // Get cursor position relative to the chart
- // var offset = chart.offset();
- // var cursorPos = [
- // evt.originalEvent.pageX - offset.left,
- // evt.originalEvent.pageY - offset.top
- // ];
- // var move = -(evt.originalEvent.detail) || evt.originalEvent.wheelDelta;
- // if (move <= 0) { zoomOut(cursorPos); }
- // else { zoomIn(cursorPos); }
- // }
- // });
-
// Modern wheel event handler for better trackpad support (pinch-to-zoom) and momentum
var momentumTimer = null;
var trackpadGestureTimer = null;
@@ -824,7 +789,6 @@ RED.view = (function() {
if (evt.ctrlKey || evt.altKey || spacebarPressed) {
evt.preventDefault();
evt.stopPropagation();
-
var currentTime = Date.now();
var timeSinceLastEvent = currentTime - lastWheelEventTime;
@@ -845,7 +809,6 @@ RED.view = (function() {
var minZoom = calculateMinZoom();
var newScale = Math.min(RED.view.zoomConstants.MAX_ZOOM,
Math.max(minZoom, scaleFactor + scaleDelta));
-
// Session-based gesture tracking:
// - If no active gesture OR gap > gestureEndThreshold, start new gesture
// - If gap < wheelEventContinuityThreshold, continue current gesture
@@ -869,6 +832,10 @@ RED.view = (function() {
var currentScrollPos = [chart.scrollLeft(), chart.scrollTop()];
var focalPoint = RED.view.zoomAnimator.getGestureFocalPoint(currentScrollPos, scaleFactor);
zoomView(newScale, focalPoint); // Direct call, no animation
+ } else {
+ // At a limit - force a refresh to ensure UI elements are correctly updated
+ _redraw()
+ RED.events.emit("view:navigate");
}
// Update last event time for continuity tracking
@@ -913,6 +880,11 @@ RED.view = (function() {
var currentScrollPos = [chart.scrollLeft(), chart.scrollTop()];
var focalPoint = RED.view.zoomAnimator.getGestureFocalPoint(currentScrollPos, scaleFactor);
zoomView(newScale, focalPoint);
+ } else {
+ // At a limit - force a refresh to ensure UI elements are correctly updated
+ _redraw()
+ RED.events.emit("view:navigate");
+
}
// Update last event time for continuity tracking
@@ -963,33 +935,6 @@ RED.view = (function() {
}
});
- //add search to status-toolbar
- RED.statusBar.add({
- id: "view-search-tools",
- align: "left",
- hidden: false,
- element: $('
'+
- '' +
- '' +
- '
' +
- '' +
- '' +
- '
' +
- '' +
- '' +
- '' +
- '
' +
- '' +
- '')
- })
- $("#red-ui-view-searchtools-search").on("click", searchFlows);
- RED.popover.tooltip($("#red-ui-view-searchtools-search"),RED._('actions.search-flows'),'core:search');
- $("#red-ui-view-searchtools-prev").on("click", searchPrev);
- RED.popover.tooltip($("#red-ui-view-searchtools-prev"),RED._('actions.search-prev'),'core:search-previous');
- $("#red-ui-view-searchtools-next").on("click", searchNext);
- RED.popover.tooltip($("#red-ui-view-searchtools-next"),RED._('actions.search-next'),'core:search-next');
- RED.popover.tooltip($("#red-ui-view-searchtools-close"),RED._('common.label.close'));
-
// Handle nodes dragged from the palette
chart.droppable({
accept:".red-ui-palette-node",
@@ -1237,6 +1182,55 @@ RED.view = (function() {
RED.view.navigator.init();
RED.view.tools.init();
+ RED.statusBar.add({
+ id: "view-zoom-controls",
+ align: "left",
+ element: $('
'+
+ ''+
+ ''+
+ ''+
+ ''+
+ '')
+ })
+
+ $("#red-ui-view-zoom-out").on("click", function() { zoomOut(); });
+ RED.popover.tooltip($("#red-ui-view-zoom-out"),RED._('actions.zoom-out'),'core:zoom-out');
+ $("#red-ui-view-zoom-zero").on("click", zoomZero);
+ RED.popover.tooltip($("#red-ui-view-zoom-zero"),RED._('actions.zoom-reset'),'core:zoom-reset');
+ $("#red-ui-view-zoom-in").on("click", function() { zoomIn(); });
+ RED.popover.tooltip($("#red-ui-view-zoom-in"),RED._('actions.zoom-in'),'core:zoom-in');
+ $("#red-ui-view-zoom-fit").on("click", zoomToFitAll);
+ RED.popover.tooltip($("#red-ui-view-zoom-fit"),RED._('actions.zoom-fit'),'core:zoom-fit');
+
+ //add search to status-toolbar
+ RED.statusBar.add({
+ id: "view-search-tools",
+ align: "left",
+ hidden: false,
+ element: $('
'+
+ '' +
+ '' +
+ '
' +
+ '' +
+ '' +
+ '
' +
+ '' +
+ '' +
+ '' +
+ '
' +
+ '' +
+ '')
+ })
+ $("#red-ui-view-searchtools-search").on("click", searchFlows);
+ RED.popover.tooltip($("#red-ui-view-searchtools-search"),RED._('actions.search-flows'),'core:search');
+ $("#red-ui-view-searchtools-prev").on("click", searchPrev);
+ RED.popover.tooltip($("#red-ui-view-searchtools-prev"),RED._('actions.search-prev'),'core:search-previous');
+ $("#red-ui-view-searchtools-next").on("click", searchNext);
+ RED.popover.tooltip($("#red-ui-view-searchtools-next"),RED._('actions.search-next'),'core:search-next');
+ RED.popover.tooltip($("#red-ui-view-searchtools-close"),RED._('common.label.close'));
+
+
+
RED.view.annotations.register("red-ui-flow-node-docs",{
type: "badge",
class: "red-ui-flow-node-docs",
@@ -2960,6 +2954,8 @@ RED.view = (function() {
}
animatedZoomView(Math.max(scaleFactor - RED.view.zoomConstants.ZOOM_STEP, minZoom), useFocalPoint, buttonZoomWorkspaceCenter);
+ } else {
+ // RED.events.emit("view:navigate"); // Ensure UI updates to reflect zoom limit reached
}
}
function zoomZero() {
@@ -3063,6 +3059,7 @@ RED.view = (function() {
onStep: function(values) {
chart.scrollLeft(values.scrollLeft);
chart.scrollTop(values.scrollTop);
+ RED.events.emit("view:navigate");
},
onStart: function() {
RED.events.emit("view:navigate");
@@ -3089,7 +3086,6 @@ RED.view = (function() {
factor = 1
}
- console.log(factor)
var screenSize = [chart.width(),chart.height()];
var scrollPos = [chart.scrollLeft(),chart.scrollTop()];
var oldScaleFactor = scaleFactor;
@@ -3144,6 +3140,7 @@ RED.view = (function() {
// If we're already at the target, no need to animate
// Use a more tolerant threshold to account for floating-point precision
if (Math.abs(scaleFactor - targetFactor) < 0.01) {
+ RED.events.emit("view:navigate");
return;
}
// Make scale 1 'sticky'
@@ -3217,6 +3214,8 @@ RED.view = (function() {
eventLayer.attr("transform", "scale(" + scaleFactor + ")");
outer.attr("width", space_width * scaleFactor).attr("height", space_height * scaleFactor);
RED.view.navigator.resize();
+ _redraw()
+ RED.events.emit("view:navigate");
},
onStart: function() {
// Show minimap when zoom animation starts
@@ -3227,15 +3226,18 @@ RED.view = (function() {
// Ensure scaleFactor is exactly the target to prevent precision issues
scaleFactor = targetFactor;
// Full redraw at the end to ensure everything is correct
- redraw();
+ _redraw();
if (RED.settings.get("editor.view.view-store-zoom")) {
RED.settings.setLocal('zoom-level', targetFactor.toFixed(1));
}
+ RED.events.emit("view:navigate");
},
onCancel: function() {
cancelInProgressAnimation = null;
// Ensure scaleFactor is set to current target on cancel
scaleFactor = targetFactor;
+ _redraw();
+ RED.events.emit("view:navigate");
}
});
}
@@ -3287,6 +3289,7 @@ RED.view = (function() {
// Apply new scroll position
chart.scrollLeft(newScrollX);
chart.scrollTop(newScrollY);
+ RED.events.emit("view:navigate");
// Stop if velocity is too small
if (Math.abs(scrollVelocity.x) < MIN_VELOCITY && Math.abs(scrollVelocity.y) < MIN_VELOCITY) {
@@ -7870,6 +7873,7 @@ RED.view = (function() {
if (x !== undefined && y !== undefined) {
chart.scrollLeft(chart.scrollLeft()+x);
chart.scrollTop(chart.scrollTop()+y)
+ RED.events.emit("view:navigate");
} else {
return [chart.scrollLeft(), chart.scrollTop()]
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js b/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js
index 78e1399cd..b0d653a0b 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js
@@ -497,17 +497,119 @@ RED.workspaces = (function() {
$("#red-ui-workspace-footer").children().hide()
}
+ const scrollbars = {}
+ function updateScrollbars() {
+ const scaleFactor = RED.view.scale();
+ const chartWindowSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()];
+ const chartSize = [ $("#red-ui-workspace-scroll-spacer").width(), $("#red-ui-workspace-scroll-spacer").height()];
+ const scrollPos = [$("#red-ui-workspace-chart").scrollLeft(), $("#red-ui-workspace-chart").scrollTop()];
+ const scrollRatio = [scrollPos[0]/(chartSize[0] - chartWindowSize[0]), scrollPos[1]/(chartSize[1] - chartWindowSize[1]) ];
+ const scrollbarSize = [scrollbars.h.bar.width(), scrollbars.v.bar.height()]
+ // Set the height of the handles to be the same ratio of chartWindowSize to chartSize, with a minimum size to ensure they are always draggable
+
+ scrollbars.v.handle.height(Math.max(40, scrollbarSize[1] * chartWindowSize[1] / chartSize[1]))
+ scrollbars.h.handle.width(Math.max(40, scrollbarSize[0] * chartWindowSize[0] / chartSize[0]))
+ if (isNaN(scrollRatio[0])) {
+ scrollbars.h.bar.hide()
+ } else {
+ scrollbars.h.bar.show()
+ const sbhWidth = scrollbars.h.bar.width() - scrollbars.h.handle.width()
+ scrollbars.h.handle.css({ left: sbhWidth * scrollRatio[0] })
+ }
+ if (isNaN(scrollRatio[1])) {
+ scrollbars.v.bar.hide()
+ } else {
+ scrollbars.v.bar.show()
+ const sbvHeight = scrollbars.v.bar.height() - scrollbars.v.handle.height()
+ scrollbars.v.handle.css({ top: sbvHeight * scrollRatio[1] })
+ }
+ }
+
+ function setupScrollbar(scrollbar, direction) {
+ // direction: 'h' | 'v'
+ let isDragging = false;
+ let dragStartPos = 0;
+ let handleStartPos = 0;
+ function cancelScroll () {
+ isDragging = false;
+ $(document).off('mousemove.red-ui-workspace-scrollbar');
+ $(document).off('mouseup.red-ui-workspace-scrollbar');
+ }
+ // Update the following event handlers to also handle touch events
+ scrollbar.handle.on('mousedown', function(evt) {
+ isDragging = true;
+ dragStartPos = (direction === 'h' ? evt.pageX : evt.pageY);
+ handleStartPos = parseInt(scrollbar.handle.css(direction === 'h' ? 'left' : 'top')) || 0;
+ evt.preventDefault();
+ $(document).on('mousemove.red-ui-workspace-scrollbar', function(evt) {
+ if (isDragging) {
+ const delta = (direction === 'h' ? evt.pageX : evt.pageY) - dragStartPos;
+ const newHandlePos = handleStartPos + delta;
+ const barSize = (direction === 'h' ? scrollbar.bar.width() : scrollbar.bar.height()) - (direction === 'h' ? scrollbar.handle.width() : scrollbar.handle.height());
+ const clampedHandlePos = Math.max(0, Math.min(newHandlePos, barSize));
+ const scrollRatio = clampedHandlePos / barSize;
+ const chartWindowSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()];
+ const chartSize = [ $("#red-ui-workspace-scroll-spacer").width(), $("#red-ui-workspace-scroll-spacer").height()];
+ if (direction === 'h') {
+ const newScrollLeft = scrollRatio * (chartSize[0] - chartWindowSize[0]);
+ $("#red-ui-workspace-chart").scrollLeft(newScrollLeft);
+ } else {
+ const newScrollTop = scrollRatio * (chartSize[1] - chartWindowSize[1]);
+ $("#red-ui-workspace-chart").scrollTop(newScrollTop);
+ }
+ updateScrollbars()
+ } else {
+ $(document).off('mousemove.red-ui-workspace-scrollbar');
+ }
+ })
+ $(document).on('mouseup.red-ui-workspace-scrollbar', function(evt) {
+ cancelScroll()
+ })
+ });
+ }
+
function init() {
- $('
').appendTo("#red-ui-workspace");
- $('
').appendTo("#red-ui-workspace");
+ $('
').appendTo("#red-ui-header-tabs");
+ $('
').appendTo("#red-ui-header-tabs");
$('
').appendTo("#red-ui-workspace");
$('
').appendTo("#red-ui-workspace");
- $('').appendTo("#red-ui-workspace");
+ $('').insertAfter("#red-ui-workspace");
+
+ scrollbars.v = { bar: $('
').appendTo("#red-ui-workspace") }
+ scrollbars.v.handle = scrollbars.v.bar.children().first();
+ setupScrollbar(scrollbars.v, 'v')
+ scrollbars.h = { bar: $('
').appendTo("#red-ui-workspace") }
+ scrollbars.h.handle = scrollbars.h.bar.children().first();
+ setupScrollbar(scrollbars.h, 'h')
+
$('
').appendTo("#red-ui-workspace");
-
createWorkspaceTabs();
- RED.events.on("sidebar:resize",workspace_tabs.resize);
+ RED.events.on("view:navigate", function () {
+ updateScrollbars()
+ })
+ RED.events.on("sidebar:resize",function () {
+ workspace_tabs.resize();
+ let sidebarWidth = $("#red-ui-sidebar-container").width()
+ const workspaceTargetWidth = $("#red-ui-workspace").width() - sidebarWidth
+ // $("#red-ui-workspace-toolbar").width(workspaceTargetWidth)
+ // $("#red-ui-workspace-footer").width(workspaceTargetWidth)
+ $("#red-ui-workspace-scroll-v").css({ right: sidebarWidth + 2})
+ $("#red-ui-workspace-scroll-h").css({ width: workspaceTargetWidth - 15 })
+
+ const paletteWidth = $("#red-ui-sidebar-left").width()
+ $("#red-ui-header-logo").width(paletteWidth - 5)
+
+ // const workspacePosition = $("#red-ui-workspace").position()
+ // $("#red-ui-header-tabs").css({ left: workspacePosition.left, width: workspaceTargetWidth })
+ updateScrollbars()
+ });
+
+ RED.events.on("workspace:change", function(event) {
+ setTimeout(() => {
+ updateScrollbars()
+ }, 100)
+ });
RED.events.on("workspace:clear", () => {
// Reset the index used to generate new flow names
@@ -534,7 +636,8 @@ RED.workspaces = (function() {
});
$(window).on("resize", function() {
- workspace_tabs.resize();
+ // workspace_tabs.resize();
+ updateScrollbars()
});
if (RED.settings.theme("menu.menu-item-workspace-add", true)) {
RED.actions.add("core:add-flow",function(opts) { addWorkspace(undefined,undefined,opts?opts.index:undefined)});
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/colors.scss b/packages/node_modules/@node-red/editor-client/src/sass/colors.scss
index dd3444b67..38af32426 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/colors.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/colors.scss
@@ -248,6 +248,8 @@ $clipboard-textarea-background: #F3E7E7;
$header-background: $primary-background;
$header-button-border: $primary-border-color;
+$header-button-background: $header-background;
+$header-button-background-hover: #ddd;
$header-button-background-active: $workspace-button-background-active;
$header-accent: $primary-background;
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/editor.scss b/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
index 0a0693aba..0e16b5df8 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
@@ -30,8 +30,7 @@
position:absolute;
margin: 8px 0 8px 7px;
top: 0;
- bottom: 0;
- //min-width: 500px;
+ bottom: 34px;
width: auto;
right: -1000px;
box-sizing: border-box;
@@ -50,7 +49,7 @@
background: var(--red-ui-secondary-background);
border: 1px solid var(--red-ui-primary-border-color);
overflow: hidden;
- box-shadow: -2px 0 6px var(--red-ui-shadow);
+ // box-shadow: -2px 0 6px var(--red-ui-shadow);
}
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/header.scss b/packages/node_modules/@node-red/editor-client/src/sass/header.scss
index 171033756..f27be4d98 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/header.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/header.scss
@@ -34,11 +34,15 @@
display: flex;
justify-content: space-between;
align-items: center;
- padding-top: 6px;
- span.red-ui-header-logo {
- float: left;
+ #red-ui-header-logo {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
margin-left: 8px;
+ min-width: 170px;
+ }
+ span.red-ui-header-logo {
text-decoration: none;
white-space: nowrap;
@@ -63,12 +67,15 @@
}
.red-ui-header-toolbar {
- display: flex;
+ flex: 1 0 auto;
+ &:not(.hide) {
+ display: flex;
+ }
align-items: stretch;
padding: 0;
- margin: 0 10px 0 0;
+ margin: 0 10px 0 20px;
list-style: none;
- gap: 15px;
+ gap: 10px;
> li {
display: inline-flex;
@@ -80,26 +87,27 @@
}
.button {
- height: 24px;
+ height: 30px;
display: inline-flex;
align-items: center;
justify-content: center;
- min-width: 24px;
+ min-width: 32px;
text-align: center;
font-size: 16px;
padding: 0px;
text-decoration: none;
color: var(--red-ui-header-menu-color);
- margin: auto 0;
vertical-align: middle;
mask-size: contain;
+ border-radius: 4px;
+ box-sizing: border-box;
&:active, &.active {
background: var(--red-ui-header-button-background-active);
}
- &:focus {
- outline: none;
- }
+ &:hover {
+ background: var(--red-ui-header-button-background-hover);
+ }
}
.button-group {
@@ -109,7 +117,6 @@
& > a {
display: inline-block;
position: relative;
- float: left;
line-height: 22px;
font-size: 14px;
text-decoration: none;
@@ -303,11 +310,13 @@
}
}
-
-.red-ui-user-profile {
+#red-ui-header-button-user {
background-color: var(--red-ui-header-background);
border: 1px solid var(--red-ui-header-button-border);
border-radius: 4px;
+}
+
+.red-ui-user-profile {
overflow: hidden;
padding: 3px;
background-position: center center;
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss b/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss
index 28eeba3c2..8bdcdc1fc 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss
@@ -140,7 +140,7 @@
vertical-align: middle;
}
.button-group:not(:last-child) {
- margin-right: 10px;
+ margin-right: 4px;
}
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/palette.scss b/packages/node_modules/@node-red/editor-client/src/sass/palette.scss
index f53a36db9..864f6225e 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/palette.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/palette.scss
@@ -263,7 +263,6 @@
width: 24px;
height: 20px;
line-height: 20px;
- margin-top: 1px;
// width: 30px;
// height: 25px;
border-radius: 3px;
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/sidebar.scss b/packages/node_modules/@node-red/editor-client/src/sass/sidebar.scss
index 822bf6438..29ef01475 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/sidebar.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/sidebar.scss
@@ -16,16 +16,20 @@
* limitations under the License.
**/
+ #red-ui-sidebar-container {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ display: flex;
+ flex-direction: row;
+ }
.red-ui-sidebar {
position: relative;
flex-grow: 0;
flex-shrink: 0;
width: 315px;
- margin: 4px 0;
- @include mixins.component-border;
- border-left: none;
- border-right: none;
- background: var(--red-ui-secondary-background);
+ margin: 4px 0 40px 0;
box-sizing: border-box;
z-index: 12;
display: flex;
@@ -34,12 +38,13 @@
}
.red-ui-sidebar-left {
background: var(--red-ui-primary-background);
- margin: 0;
+ margin-top: 0px;
+ margin-left: 5px;
border: none;
z-index: 10;
}
.red-ui-sidebar-right {
- margin-left: 0;
+ margin-right: 5px;
}
.red-ui-sidebar-footer {
@@ -51,27 +56,31 @@
}
.red-ui-sidebar-section {
- margin: 4px;
+ margin: 8px 4px 0 4px;
display: flex;
flex-direction: column;
min-height: 80px;
- background: rgba(0,0,255,0.2);
+ // background: rgba(0,0,255,0.2);
flex-grow: 0;
flex-shrink: 0;
border-radius: 6px;
- border: 1px solid var(--red-ui-secondary-border-color);
+ border: 1px solid var(--red-ui-primary-border-color);
overflow: hidden;
+ &.red-ui-sidebar-section-top { margin-top: 4px; }
&.red-ui-sidebar-section-bottom {
+ &:first-child {
+ margin-top: 4px;
+ }
flex-grow: 1;
flex-shrink: 1;
}
}
.red-ui-sidebar-left .red-ui-sidebar-section {
margin-left: 0;
- border-color: var(--red-ui-primary-border-color);
+ &.red-ui-sidebar-section-top { margin-top: 0; }
}
.red-ui-sidebar-right .red-ui-sidebar-section {
- margin-right: 0
+ margin-right: 0;
}
@@ -99,11 +108,10 @@
.red-ui-sidebar-separator-handle {
position: absolute;
- // background: rgba(255,140,0,0.2);
top: 0;
left: -6px;
width: 12px;
- height: 100%;
+ height: calc(100% - 40px);;
z-index: 20;
}
}
@@ -127,31 +135,24 @@
}
.red-ui-sidebar-tab-bar {
- background-color: var(--red-ui-secondary-background);
- flex: 0 0 auto;
display: flex;
- flex-direction: column;
+ flex-direction: row;
+ flex: 0 0 auto;
align-items: center;
- margin: 4px;
- @include mixins.component-border;
+ flex-wrap: nowrap;
+ margin: 0;
z-index: 12;
overflow: hidden;
- // border: 1px solid var(--red-ui-primary-border-color);
+ // background: rgba(243, 160, 204, 0.617);
&.red-ui-sidebar-left {
z-index: 10;
- border: none;
- margin-right: 0;
- margin-left: 0;
- background: var(--red-ui-primary-background);
+ margin-left: 5px;
+ background: none;
}
&.red-ui-sidebar-right {
- border-top-right-radius: 8px;
- border-bottom-right-radius: 8px;
- margin-left: 0;
- // Account for the RH sidebar having an extra top margin
- padding-top: 4px;
- border-left: none;
+ border-bottom: none;
+ justify-content: flex-end;
}
button {
@@ -162,17 +163,21 @@
align-items: center;
justify-content: center;
padding: 0;
- height: 22px;
- width: 22px;
+ height: 28px;
+ width: 28px;
&:not(.selected):not(:hover) {
- border: none;
i {
- opacity: 0.7;
+ opacity: 1;
}
}
i {
font-size: 13px;
}
+ border-color: var(--red-ui-secondary-border-color);
+ &.selected {
+ background-color: var(--red-ui-secondary-color);
+ border-color: var(--red-ui-primary-border-color);
+ }
}
.red-ui-sidebar-tab-bar-button-placeholder {
border: 1px dashed var(--red-ui-form-input-border-color) !important;
@@ -180,33 +185,55 @@
.red-ui-sidebar-tab-bar-buttons {
display: flex;
- width: 100%;
// background-color: var(--red-ui-primary-background);
- // background: rgba(255, 0, 0, 0.1);
- padding: 6px;
+ // background: rgba(233, 255, 91, 0.555);
+
+ height: 28px;
+ padding: 0 6px;
box-sizing: border-box;
- flex-direction: column;
+ flex-direction: row;
align-items: center;
- gap: 10px;
- flex-grow: 1;
+ gap: 8px;
+ flex-grow: 0;
// height: 50%;
- &:first-child {
- // background: rgba(255,0,0,0.1);
- flex-grow: 0;
- flex-shrink: 0;
- }
- &:last-child {
- // background: rgba(255,255,0,0.1);
- flex-grow: 1;
- flex-shrink: 1;
- }
+ // &:first-child {
+ // // background: rgba(255,0,0,0.1);
+ // flex-grow: 0;
+ // flex-shrink: 0;
+ // }
+ // &:last-child {
+ // // background: rgba(255,255,0,0.1);
+ // flex-grow: 1;
+ // flex-shrink: 1;
+ // }
+ }
+ .red-ui-sidebar-tab-bar-buttons.red-ui-sidebar-tab-bar-empty {
+ display: none;
+ // background: rgba(255,0,0,0.3);
+ }
+ &.red-ui-sidebar-dragging-tab .red-ui-sidebar-tab-bar-empty {
+ display: flex;
}
&.red-ui-sidebar-dragging-tab .red-ui-sidebar-tab-bar-buttons:last-child {
- border-top: 2px dashed var(--red-ui-form-input-border-color);
- margin-top: -2px;
+ border-left: 2px dashed var(--red-ui-secondary-border-color);
+ // margin-left: -2px;
+ width: 42px;
+ height: 28px;
+ }
+ .red-ui-sidebar-tab-bar-buttons:last-child {
+ min-width: 28px;
+ border-left: 2px solid var(--red-ui-secondary-border-color);
+ }
+ .red-ui-sidebar-right & {
+ justify-items: flex-end;
}
}
+.red-ui-sidebar-right .red-ui-sidebar-tab-bar-buttons:first-child {
+ padding-left: 20px;
+}
+
+
.red-ui-sidebar .button {
@include mixins.workspace-button;
line-height: 18px;
@@ -215,14 +242,27 @@
padding: 2px 8px;
}
+.red-ui-sidebar-banner { /* Currently unused... */
+ background: var(--red-ui-primary-background);
+ color: var(--red-ui-primary-text-color);
+ font-size: 8px;
+ padding: 0 3px;
+ text-align: right;
+ user-select: none;
+ cursor: grab;
+}
.sidebar-header, /* Deprecated -> red-ui-sidebar-header */
.red-ui-sidebar-header {
+ font-size: 13px;
color: var(--red-ui-primary-text-color);
- text-align: right;
- padding: 8px 10px;
+ padding: 4px;
background: var(--red-ui-primary-background);
border-bottom: 1px solid var(--red-ui-secondary-border-color);
white-space: nowrap;
+ display: flex;
+ justify-content: end;
+ align-items: center;
+ gap: 6px;
}
/* Deprecated -> red-ui-footer-button */
@@ -239,9 +279,9 @@ button.sidebar-header-button, /* Deprecated -> red-ui-sidebar-header-button */
a.red-ui-sidebar-header-button,
button.red-ui-sidebar-header-button {
@include mixins.workspace-button;
- font-size: 13px;
- line-height: 13px;
- padding: 5px 8px;
+ font-size: 11px;
+ line-height: 11px;
+ padding: 3px 5px;
&.toggle {
@include mixins.workspace-button-toggle;
}
@@ -252,9 +292,9 @@ button.sidebar-header-button-toggle, /* Deprecated -> red-ui-sidebar-header-butt
a.red-ui-sidebar-header-button-toggle,
button.red-ui-sidebar-header-button-toggle {
@include mixins.workspace-button-toggle;
- font-size: 13px;
- line-height: 13px;
- padding: 5px 8px;
+ font-size: 11px;
+ line-height: 11px;
+ padding: 3px 5px;
}
.sidebar-header-button:not(:first-child), /* Deprecated -> red-ui-sidebar-header-button */
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/sizes.scss b/packages/node_modules/@node-red/editor-client/src/sass/sizes.scss
index ecefc0294..449819d45 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/sizes.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/sizes.scss
@@ -14,4 +14,4 @@
* limitations under the License.
**/
- $header-height: 36px;
\ No newline at end of file
+ $header-height: 40px;
\ No newline at end of file
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss b/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss
index 5af00579f..8cbf8b0d3 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss
@@ -23,27 +23,17 @@
.red-ui-sidebar-info hr {
margin: 10px 0;
}
-.red-ui-info-header {
- padding-left: 9px;
- line-height: 21px;
- cursor: default;
- border-bottom: 1px solid var(--red-ui-secondary-border-color);
- > * {
- vertical-align: middle
- }
- > span {
- display: inline-block;
- margin-left: 5px;
- overflow-wrap: anywhere;
- }
-}
+
table.red-ui-info-table {
- font-size: 14px;
+ font-size: 13px;
margin: 0 0 10px;
width: 100%;
}
table.red-ui-info-table tr:not(.blank) {
- border-top: 1px solid var(--red-ui-secondary-border-color);
+ &:not(:first-child) {
+ border-top: 1px solid var(--red-ui-secondary-border-color);
+ }
+ line-height: 23px;
border-bottom: 1px solid var(--red-ui-secondary-border-color);
}
.red-ui-help-property-expand {
@@ -360,7 +350,7 @@ div.red-ui-info-table {
.red-ui-info-outline-item {
display: inline-flex;
padding: 0;
- font-size: 13px;
+ font-size: 12px;
border: none;
&:not(.red-ui-node-list-item) .red-ui-palette-icon-fa {
position: relative;
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/tabs.scss b/packages/node_modules/@node-red/editor-client/src/sass/tabs.scss
index 3b7d655d1..0b0785965 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/tabs.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/tabs.scss
@@ -230,7 +230,6 @@
left: 0;
right: 0;
opacity: 0.4;
- background: red;
}
}
.red-ui-tab-button {
@@ -284,9 +283,8 @@
width: 21px;
top: 0;
a {
- height: 35px;
+ // height: 35px;
width: 21px;
- display: block;
color: var(--red-ui-workspace-button-color);
font-size: 22px;
text-align: center;
@@ -295,7 +293,6 @@
border-right: none;
border-top: none;
border-bottom: 1px solid var(--red-ui-primary-border-color);
- line-height: 34px;
}
}
.red-ui-tab-scroll-left {
@@ -435,19 +432,126 @@ i.red-ui-tab-icon {
}
}
-ul#red-ui-workspace-tabs {
- border-color: var(--red-ui-secondary-border-color);
- li {
- border-color: var(--red-ui-secondary-border-color);
- border-top-left-radius: 4px;
- border-top-right-radius: 4px;
+#red-ui-header-tabs {
+ flex: 1 1 100%;
+ border-right: 1px solid var(--red-ui-secondary-border-color);
+ padding-right: 5px;
+
+ .red-ui-tabs {
+ background: var(--red-ui-header-background);
+ border: none;
+ display: flex;
+ padding: 0;
+ .red-ui-tabs-scroll-container {
+ min-width:0;
+ width: 0;
+ flex: 1 1 0;
+ }
+ .red-ui-tab-button {
+ position: static;
+ background: var(--red-ui-header-background);
+ border: var(--red-ui-header-button-border);
+ a {
+ background: var(--red-ui-header-background);
+ border: var(--red-ui-header-button-border);
+ &:hover {
+ background: var(--red-ui-header-button-background-hover);
+ }
+ }
+ }
+ .red-ui-tab-button.red-ui-tab-scroll {
+ background: none;
+ border: none;
+ z-index:10;
+ border-radius: 0;
+ }
+ .red-ui-tab-button.red-ui-tab-scroll a {
+ border: none;
+ background: none;
+ border-radius: 0;
+ box-shadow: 0 0 8px rgba(0,0,0,0.3);
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ .red-ui-tab-button.red-ui-tab-scroll.red-ui-tab-scroll-left a {
+ border: none;
+ clip-path: inset(0 -8px 0 0);
+ }
+ .red-ui-tab-button.red-ui-tab-scroll.red-ui-tab-scroll-right a {
+ border: none;
+ clip-path: inset(0 0 0 -8px);
+ }
+ }
+ ul {
+ display: flex;
+ align-items: center;
+ border: none;
+ gap: 2px;
+
+ li {
+ min-width: 60px;
+ max-width: 150px;
+ flex: 1 1 100%;
+ border-color: transparent;
+ margin: 0;
+ background: transparent;
+
+ a.red-ui-tab-label {
+ padding: 0 6px;
+ text-align: center;
+ width: auto;
+
+ i.red-ui-tab-icon:not(.fa) {
+ margin-left: 0;
+ }
+ }
+
+ &:not(.active) .red-ui-tabs-fade {
+ display: none;
+ }
+
+ &:not(.active) {
+ border-radius: 0;
+ }
+
+ &:not(:first-child):not(.active) {
+ box-shadow: -1px 0 0 rgba(0,0,0,0.15);
+ }
+
+ &:not(:first-child):not(.active):hover,
+ &.active + li:not(:first-child),
+ &:hover + li:not(:first-child):not(.active) {
+ box-shadow: none;
+ }
+
+ &.active {
+ background: var(--red-ui-secondary-background);
+ box-shadow: 0 1px 4px rgba(0,0,0,0.15);
+ border-color: var(--red-ui-primary-border-color);
+ border-radius: 4px;
+ }
+
+ &:not(.active):hover::after {
+ content: '';
+ position: absolute;
+ inset: 0 0 0 1px;
+ background: rgba(0,0,0,0.06);
+ border-radius: 4px;
+ pointer-events: none;
+ }
+
+ &:not(.active) a:hover {
+ background: transparent;
+ }
+ }
}
}
-#red-ui-workspace > .red-ui-tabs > .red-ui-tab-button {
- border-color: var(--red-ui-secondary-border-color);
+#red-ui-header-tabs > .red-ui-tabs > .red-ui-tab-button {
+ border-color: var(--red-ui-header-button-border);
}
-#red-ui-workspace > .red-ui-tabs > .red-ui-tab-scroll a {
- border-color: var(--red-ui-secondary-border-color);
- border-radius: 0;
+#red-ui-header-tabs > .red-ui-tabs > .red-ui-tab-scroll a {
+ border-color: var(--red-ui-header-button-border);
}
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/variables.scss b/packages/node_modules/@node-red/editor-client/src/sass/variables.scss
index fca7d05db..4e9459add 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/variables.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/variables.scss
@@ -249,7 +249,10 @@
--red-ui-header-background: #{colors.$header-background};
--red-ui-header-accent: #{colors.$header-accent};
+ --red-ui-header-button-background: #{colors.$header-background};
+ --red-ui-header-button-background-hover: #{colors.$header-button-background-hover};
--red-ui-header-button-background-active: #{colors.$header-button-background-active};
+
--red-ui-header-button-border: #{colors.$header-button-border};
--red-ui-header-menu-color: #{colors.$header-menu-color};
--red-ui-header-menu-color-disabled: #{colors.$header-menu-color-disabled};
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss b/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss
index 6391292db..f350ca2aa 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss
@@ -20,37 +20,37 @@
margin: 0;
overflow: hidden;
@include mixins.component-border;
- border-top-left-radius: 8px;
- border-bottom-left-radius: 8px;
+ border-top-left-radius: 6px;
border-right: none;
- margin: 4px 0 4px;
+ border-bottom: none;
transition: left 0.1s ease-in-out;
position: relative;
flex-grow: 1;
+ .red-ui-workspace-toolbar-active {
+ top: 40px;
+ }
}
#red-ui-workspace-chart {
- overflow: auto;
- position: absolute;
- bottom:0;
- top: 35px;
- left:0px;
- right:0px;
- box-sizing:border-box;
- transition: right 0.2s ease;
- touch-action: none;
- padding: 0;
- margin: 0;
- border-right: 1px solid var(--red-ui-secondary-border-color);
-// border-top-right-radius: px;
+ overflow: auto;
+ position: absolute;
+ bottom:0;
+ top: 0px;
+ left:0px;
+ right:0px;
+ box-sizing:border-box;
+ transition: right 0.2s ease;
+ touch-action: none;
+ padding: 0;
+ margin: 0;
-// // Hide scrollbars
-// scrollbar-width: none; /* Firefox */
-// -ms-overflow-style: none; /* Internet Explorer 10+ */
-// &::-webkit-scrollbar { /* WebKit */
-// width: 0;
-// height: 0;
-// }
+ // Hide scrollbars
+ scrollbar-width: none; /* Firefox */
+ -ms-overflow-style: none; /* Internet Explorer 10+ */
+ &::-webkit-scrollbar { /* WebKit */
+ width: 0;
+ height: 0;
+ }
// Reset SVG default margins
> svg {
@@ -88,9 +88,9 @@
}
}
-#red-ui-workspace-tabs:not(.red-ui-workspace-focussed) {
- opacity:0.8;
-}
+// #red-ui-workspace-tabs:not(.red-ui-workspace-focussed) {
+// opacity:0.8;
+// }
.red-ui-workspace-disabled-icon {
display: none;
}
@@ -128,18 +128,6 @@
}
.red-ui-workspace-locked {
&.red-ui-tab {
- // border-top-style: dashed;
- // border-left-style: dashed;
- // border-right-style: dashed;
-
- // a {
- // font-style: italic;
- // color: var(--red-ui-tab-text-color-disabled-inactive) !important;
- // }
- // &.active a {
- // font-weight: normal;
- // color: var(--red-ui-tab-text-color-disabled-active) !important;
- // }
.red-ui-workspace-locked-icon {
display: inline;
}
@@ -149,7 +137,7 @@
#red-ui-navigator-canvas {
position: absolute;
bottom: 0;
- right:0;
+ left:0;
z-index: 101;
border: 1px solid var(--red-ui-primary-border-color);
background: var(--red-ui-view-navigator-background);
@@ -157,6 +145,10 @@
border-radius: 4px;
}
+#view-zoom-controls .button-group button.red-ui-footer-button:not(:last-child) {
+ border-right: none;
+}
+
.red-ui-navigator-container {
transition: opacity 0.3s ease;
opacity: 0;
@@ -176,11 +168,17 @@
opacity: 0.6;
}
#red-ui-workspace-footer {
+ display: flex;
+ flex-direction: row;
+ gap: 10px;
+ align-items: center;
border: none;
background: none;
- bottom: 14px;
- right: 12px;
+ bottom: 8px;
+ right: 0;
+ left: 0;
padding: 0;
+ // background: rgba(230,230,255,0.8);
}
.red-ui-component-footer {
@include mixins.component-footer;
@@ -210,28 +208,42 @@ a.red-ui-footer-button-toggle,
button.red-ui-footer-button-toggle {
@include mixins.component-footer-button-toggle;
}
+#red-ui-statusbar {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 4px;
+ // background: rgba(62, 236, 53, 0.8);
+ flex: 1 1 100%;
+ height: 100%;
+ padding-left: 5px;
+}
.red-ui-statusbar-widget {
+ line-height: 1em;
margin: 0 2px;
display: inline-block;
vertical-align: middle;
height: 100%;
- line-height: 20px;
+ & .red-ui-footer-button,
+ & .red-ui-footer-button-toggle {
+ min-width: 28px;
+ height: 28px;
+ }
}
.red-ui-statusbar-bucket {
- position: absolute;
- top: 0;
- bottom: 0;
+ display: flex;
+ align-items: center;
+ flex: 1 1 auto;
}
.red-ui-statusbar-bucket-left {
- left: 6px;
+ flex: 0 0 auto;
.red-ui-statusbar-widget:first-child {
margin-left: 0;
}
}
.red-ui-statusbar-bucket-right {
- right: 6px;
.red-ui-statusbar-widget:last-child {
margin-right: 0;
}
@@ -277,3 +289,58 @@ button.red-ui-footer-button-toggle {
font-size: 13px;
margin-bottom: 2px;
}
+:root {
+ --red-ui-scrollbar-width: 12px;
+ --red-ui-scrollbar-handle-size: 40px;
+ --red-ui-scrollbar-handle-background: rgb(200, 200, 200);
+}
+
+.red-ui-workspace-scrollbar {
+ position: absolute;
+ // background: rgba(223, 236, 230, 0.8);
+}
+.red-ui-workspace-scrollbar-handle {
+ position: absolute;
+ background: var(--red-ui-scrollbar-handle-background);
+ opacity: 0.7;
+ border-radius: 4px;
+ box-sizing: border-box;
+ border: 1px solid rgba(255,255,255,1);
+ cursor: pointer;
+ overflow: visible;
+ &:hover {
+ opacity: 1;
+ }
+ .red-ui-workspace-scrollbar-handle-target {
+ position: absolute;
+ top: -5px;
+ left: -5px;
+ right: -5px;
+ bottom: -5px;
+ }
+}
+#red-ui-workspace-scroll-v {
+ top: 2px;
+ bottom: 46px;
+ right: 0;
+ width: var(--red-ui-scrollbar-width);
+ .red-ui-workspace-scrollbar-handle {
+ top: 0;
+ left: 2px;
+ width: 8px;
+ height: var(--red-ui-scrollbar-handle-size);
+ }
+}
+#red-ui-workspace-scroll-h {
+ left: 2px;
+ right: 0;
+ bottom: 36px;
+ height: var(--red-ui-scrollbar-width);
+ .red-ui-workspace-scrollbar-handle {
+ left: 0;
+ top: 2px;
+ height: 8px;
+ width: var(--red-ui-scrollbar-handle-size);
+ }
+ // background: var(--red-ui-scrollbar-background);
+}
\ No newline at end of file
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/workspaceToolbar.scss b/packages/node_modules/@node-red/editor-client/src/sass/workspaceToolbar.scss
index 7bc79f35a..c72fc2b0c 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/workspaceToolbar.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/workspaceToolbar.scss
@@ -23,7 +23,7 @@
font-size: 12px;
line-height: 18px;
position: absolute;
- top: 35px;
+ top: 0;
left:0;
right: 0;
padding: 7px;
@@ -53,6 +53,15 @@
.button-group {
@include mixins.disable-selection;
+ .button:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+ .button:not(:last-child) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+
.button:first-child {
margin-right: 0;
}
diff --git a/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js b/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js
index 20a62ea5c..fe99395f4 100644
--- a/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js
+++ b/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js
@@ -45,11 +45,11 @@ RED.debug = (function() {
''+
''+
'
'+
- ''+
+ ''+
''+
'
'+
- '' +
- ''+
+ '' +
+ ''+
' ').appendTo(content);
var footerToolbar = $('