Skip to content

Focus and keyboard navigation do not work in search results when disabled parents #652

@hh-pers

Description

@hh-pers

What is expected?

When the tree select search is used, focus is given to the first element, users can press 'Enter' to select it or use 'up' and 'down' keys to navigate other search results

Disabled elements in the search should not be given focus, but if their children are enabled their children should still be focused in search results

What is actually happening?

Any element with a disabled parent somewhere in their hierarchy is not given focus when searching, 'Enter' key will select the first element in the tree instead

This is bad UX but also not good for accessibility

I am using master from this repo during testing

Steps to reproduce
I have a demo sandbox here made with AntD but exact behaviour comes from rc-tree-select, I can adjust the demo if needed: https://codesandbox.io/p/devbox/confident-resonance-8jv7cz

The demo shows two cases, one working (No disabled parents) and one broken (Disabled parent)

To show the component not working:

Click on the treeselect search
Search for '1' (Or '2', or '3')
The child element gets focus, pressing enter on keyboard does nothing

To show the component working as expected:

Click on the treeselect search
Search for '3' (Or '4', or '5')
The child element gets focus, pressing enter on keyboard selects element

Suggested code fix - even if a parent is disabled or not selectable, check children

// ========================== Get First Selectable Node ==========================
const getFirstMatchingNode = (nodes: EventDataNode<any>[]): EventDataNode<any> | null => {
  for (const node of nodes) {
-    if (node.disabled || node.selectable === false) {
-      continue;
-    }
-
-    if (searchValue) {
-      if (filterTreeNode(node)) {
-        return node;
-      }
-    } else {
-      return node;
-    }
+    const isNodeSelectable = !node.disabled && node.selectable !== false;
+
+    if (isNodeSelectable) {
+      if (searchValue) {
+        if (filterTreeNode(node)) {
+          return node;
+        }
+      } else {
+        return node;
+      }
+    }
 
     if (node[fieldNames.children]) {
       const matchInChildren = getFirstMatchingNode(node[fieldNames.children]);
       if (matchInChildren) {
         return matchInChildren;
       }
     }
   }
   return null;
};

Demo before;

Image

Demo after;

Image

Initially created as an antD issue

Please let me know if I can provide any more information

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions