diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js
index 9ee508de6..9fca87e75 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js
@@ -24,6 +24,9 @@
* - rootSortable: boolean - if 'sortable' is set, then setting this to
* false, prevents items being sorted to the
* top level of the tree
+ * - autoSelect: boolean - default true - triggers item selection when navigating
+ * list by keyboard. If the list has checkboxed items
+ * you probably want to set this to false
*
* methods:
* - data(items) - clears existing items and replaces with new data
@@ -50,6 +53,7 @@
* deferBuild: true/false, // don't build any ui elements for the item's children
* until it is expanded by the user.
* element: // custom dom element to use for the item - ignored if `label` is set
+ * collapsible: true/false, // prevent a parent item from being collapsed. default true.
* }
* ]
*
@@ -90,77 +94,96 @@
$.widget( "nodered.treeList", {
_create: function() {
var that = this;
-
+ var autoSelect = true;
+ if (that.options.autoSelect === false) {
+ autoSelect = false;
+ }
this.element.addClass('red-ui-treeList');
this.element.attr("tabIndex",0);
var wrapper = $('
',{class:'red-ui-treeList-container'}).appendTo(this.element);
this.element.on('keydown', function(evt) {
- var selected = that._topList.find(".selected").parent().data('data');
- if (!selected && (evt.keyCode === 40 || evt.keyCode === 38)) {
- that.select(that._data[0]);
+ var focussed = that._topList.find(".focus").parent().data('data');
+ if (!focussed && (evt.keyCode === 40 || evt.keyCode === 38)) {
+ if (that._data[0]) {
+ if (autoSelect) {
+ that.select(that._data[0]);
+ } else {
+ that._topList.find(".focus").removeClass("focus")
+ }
+ that._data[0].treeList.label.addClass('focus')
+ }
return;
}
var target;
switch(evt.keyCode) {
+ case 32: // SPACE
case 13: // ENTER
evt.preventDefault();
evt.stopPropagation();
- if (selected.children) {
- if (selected.treeList.container.hasClass("expanded")) {
- selected.treeList.collapse()
+ if (focussed.checkbox) {
+ focussed.treeList.checkbox.trigger("click");
+ } else if (focussed.radio) {
+ focussed.treeList.radio.trigger("click");
+ } else if (focussed.children) {
+ if (focussed.treeList.container.hasClass("expanded")) {
+ focussed.treeList.collapse()
} else {
- selected.treeList.expand()
+ focussed.treeList.expand()
}
} else {
- that._trigger("confirm",null,selected)
+ that._trigger("confirm",null,focussed)
}
-
break;
case 37: // LEFT
evt.preventDefault();
evt.stopPropagation();
- if (selected.children&& selected.treeList.container.hasClass("expanded")) {
- selected.treeList.collapse()
- } else if (selected.parent) {
- target = selected.parent;
+ if (focussed.children&& focussed.treeList.container.hasClass("expanded")) {
+ focussed.treeList.collapse()
+ } else if (focussed.parent) {
+ target = focussed.parent;
}
break;
case 38: // UP
evt.preventDefault();
evt.stopPropagation();
- target = that._getPreviousSibling(selected);
+ target = that._getPreviousSibling(focussed);
if (target) {
target = that._getLastDescendant(target);
}
- if (!target && selected.parent) {
- target = selected.parent;
+ if (!target && focussed.parent) {
+ target = focussed.parent;
}
break;
case 39: // RIGHT
evt.preventDefault();
evt.stopPropagation();
- if (selected.children) {
- if (!selected.treeList.container.hasClass("expanded")) {
- selected.treeList.expand()
+ if (focussed.children) {
+ if (!focussed.treeList.container.hasClass("expanded")) {
+ focussed.treeList.expand()
}
}
break
case 40: //DOWN
evt.preventDefault();
evt.stopPropagation();
- if (selected.children && Array.isArray(selected.children) && selected.children.length > 0 && selected.treeList.container.hasClass("expanded")) {
- target = selected.children[0];
+ if (focussed.children && Array.isArray(focussed.children) && focussed.children.length > 0 && focussed.treeList.container.hasClass("expanded")) {
+ target = focussed.children[0];
} else {
- target = that._getNextSibling(selected);
- while (!target && selected.parent) {
- selected = selected.parent;
- target = that._getNextSibling(selected);
+ target = that._getNextSibling(focussed);
+ while (!target && focussed.parent) {
+ focussed = focussed.parent;
+ target = that._getNextSibling(focussed);
}
}
break
}
if (target) {
- that.select(target);
+ if (autoSelect) {
+ that.select(target);
+ } else {
+ that._topList.find(".focus").removeClass("focus")
+ }
+ target.treeList.label.addClass('focus')
}
});
this._data = [];
@@ -463,6 +486,9 @@
container.addClass("expanded");
}
item.treeList.collapse = function() {
+ if (item.collapsible === false) {
+ return
+ }
if (!item.children) {
return;
}
@@ -583,7 +609,7 @@
// Already a parent because we've got the angle-right icon
return;
}
- $('').appendTo(treeListIcon);
+ $('').toggleClass("hide",item.collapsible === false).appendTo(treeListIcon);
treeListIcon.on("click.red-ui-treeList-expand", function(e) {
e.stopPropagation();
e.preventDefault();
@@ -634,6 +660,8 @@
label.on("click", function(e) {
e.stopPropagation();
cb.trigger("click");
+ that._topList.find(".focus").removeClass("focus")
+ label.addClass('focus')
})
}
item.treeList.select = function(v) {
@@ -641,6 +669,7 @@
cb.trigger("click");
}
}
+ item.treeList.checkbox = cb;
selectWrapper.appendTo(label)
} else if (item.radio) {
var selectWrapper = $('');
@@ -669,6 +698,8 @@
label.on("click", function(e) {
e.stopPropagation();
cb.trigger("click");
+ that._topList.find(".focus").removeClass("focus")
+ label.addClass('focus')
})
}
item.treeList.select = function(v) {
@@ -677,6 +708,7 @@
}
}
selectWrapper.appendTo(label)
+ item.treeList.radio = cb;
} else {
label.on("click", function(e) {
if (!that.options.multi) {
@@ -684,10 +716,14 @@
}
label.addClass("selected");
that._selected.add(item);
+ that._topList.find(".focus").removeClass("focus")
+ label.addClass('focus')
that._trigger("select",e,item)
})
label.on("dblclick", function(e) {
+ that._topList.find(".focus").removeClass("focus")
+ label.addClass('focus')
if (!item.children) {
that._trigger("confirm",e,item);
}
@@ -835,6 +871,9 @@
if (item.treeList.label) {
item.treeList.label.addClass("selected");
}
+
+ that._topList.find(".focus").removeClass("focus");
+
if (triggerEvent !== false) {
this._trigger("select",null,item)
}
@@ -842,6 +881,9 @@
clearSelection: function() {
this._selected.forEach(function(item) {
item.selected = false;
+ if (item.treeList.checkbox) {
+ item.treeList.checkbox.prop('checked',false)
+ }
if (item.treeList.label) {
item.treeList.label.removeClass("selected")
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js
index 52606cd88..3159622b6 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js
@@ -287,11 +287,11 @@ RED.sidebar.info.outliner = (function() {
var node = RED.nodes.node(item.id) || RED.nodes.group(item.id);
if (node) {
if (node.type === 'group' || node._def.category !== "config") {
- RED.view.select({nodes:[node]})
+ // RED.view.select({nodes:[node]})
} else if (node._def.category === "config") {
RED.sidebar.info.refresh(node);
} else {
- RED.view.select({nodes:[]})
+ // RED.view.select({nodes:[]})
}
}
})
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 89ad06ca2..72422f350 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
@@ -434,16 +434,19 @@ div.red-ui-info-table {
}
.red-ui-info-outline-item-controls {
position: absolute;
- top:0;
- bottom: 0;
- right: 0px;
- padding: 2px 3px 0 1px;
+ top:1px;
+ bottom: 1px;
+ right: 1px;
+ padding: 1px 2px 0 1px;
text-align: right;
background: $list-item-background;
.red-ui-treeList-label:hover & {
background: $list-item-background-hover;
}
+ .red-ui-treeList-label.focus & {
+ background: $list-item-background-hover;
+ }
.red-ui-treeList-label.selected & {
background: $list-item-background-selected;
}
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss
index 3621328d8..beba6b047 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss
@@ -89,6 +89,12 @@
color: $list-item-color;
text-decoration: none;
}
+ &.focus, &.focus .red-ui-treeList-sublabel-text {
+ background: $list-item-background-hover;
+ outline: 1px solid $form-input-focus-color !important;
+ outline-offset: -1px;
+ color: $list-item-color;
+ }
&.selected, &.selected .red-ui-treeList-sublabel-text {
background: $list-item-background-selected;
outline: none;